You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
An implicit object that only exists as an extension method container
is a bit strange. Since extension methods can now also be made visible
by imports it makes sense to de-emphasize extension methods in implicit
values until we discuss typeclasses later in the section.
`CircleOps` adds an extension method `circumference` to values of class `Circle`. Like regular methods, extension methods can be invoked with infix `.`:
14
+
Like regular methods, extension methods can be invoked with infix `.`:
17
15
18
16
```scala
19
17
valcircle=Circle(0, 0, 1)
@@ -29,22 +27,31 @@ to the plain method, and can also be invoked as such:
When is an extension method considered? There are two possibilities. The first (and recommended one) is by defining the extension method as a member of an implicit value. The method can then be used as an extension method wherever the implicit value is applicable. The second possibility is by making the extension method itself visible under a simple name, typically by importing it. As an example, consider an extension method `longestStrings` on `String`. We can either define it like this:
35
+
When is an extension method applicable? There are two possibilities.
36
+
37
+
- An extension method is applicable if it is visible under a simple name, by being defined
38
+
or inherited or imported in a scope enclosing the application.
39
+
- An extension method is applicable if it is a member of an eligible implicit value at the point of the application.
38
40
41
+
As an example, consider an extension method `longestStrings` on `String` defined in a trait `StringSeqOps`.
39
42
40
43
```scala
41
-
implicitobjectStringSeqOps1 {
44
+
traitStringSeqOps {
42
45
def (xs: Seq[String]) longestStrings = {
43
46
valmaxLength= xs.map(_.length).max
44
47
xs.filter(_.length == maxLength)
45
48
}
46
49
}
47
50
```
51
+
We can make the extension method available by defining an implicit instance of `StringSeqOps`, like this:
52
+
```scala
53
+
implicitobjectops1extendsStringSeqOps
54
+
```
48
55
Then
49
56
```scala
50
57
List("here", "is", "a", "list").longestStrings
@@ -53,13 +60,8 @@ is legal everywhere `StringSeqOps1` is available as an implicit value. Alternati
53
60
as a member of a normal object. But then the method has to be brought into scope to be usable as an extension method.
54
61
55
62
```scala
56
-
objectStringOps2 {
57
-
def (xs: Seq[String]) longestStrings = {
58
-
valmaxLength= xs.map(_.length).max
59
-
xs.filter(_.length == maxLength)
60
-
}
61
-
}
62
-
importStringSeqOps2.longestStrings
63
+
objectops2extendsStringSeqOps
64
+
importops2.longestStrings
63
65
List("here", "is", "a", "list").longestStrings
64
66
```
65
67
The precise rules for resolving a selection to an extension method are as follows.
@@ -100,30 +102,23 @@ to the implementation of right binding operators as normal methods.
100
102
101
103
### Generic Extensions
102
104
103
-
The `StringSeqOps` examples extended a specific instance of a generic type. It is also possible
104
-
to extend a generic type by adding type parameters to an extension method:
105
+
The `StringSeqOps` examples extended a specific instance of a generic type. It is also possible to extend a generic type by adding type parameters to an extension method:
As usual, type parameters of the extension method follow the defined method name. Nevertheless, such type parameters can already be used in the preceding parameter clause.
0 commit comments