@@ -13,47 +13,71 @@ permalink: /overviews/core/:title.html
1313
1414## Introduction
1515
16- Scala 2.10 introduced a new feature called * implicit classes* . An * implicit class* is a class
17- marked with the ` implicit ` keyword. This keyword makes the class's primary constructor available
18- for implicit conversions when the class is in scope.
16+ Scala 2.10 introduced a new feature called * implicit classes* . An * implicit class* is a class
17+ marked with the ` implicit ` keyword. The ` implicit ` keyword makes the class's primary constructor available
18+ for implicit conversions when the class is in scope. This mechanism is used to add "extension methods"
19+ to the type of the class parameter.
1920
20- Implicit classes were proposed in [ SIP-13] ( https://docs.scala-lang.org/sips/pending/ implicit-classes.html ) .
21+ Implicit classes were proposed in [ SIP-13] ( https://docs.scala-lang.org/sips/implicit-classes.html ) .
2122
2223## Usage
2324
2425To create an implicit class, simply place the ` implicit ` keyword in front of an appropriate
25- class. Here's an example :
26+ class:
2627
2728 object Helpers {
28- implicit class IntWithTimes(x : Int) {
29- def times[A](f : => A): Unit = {
29+ implicit class `keep up with the times`(n : Int) {
30+ def times[A](body : => A): Unit = {
3031 def loop(current: Int): Unit =
31- if(current > 0) {
32- f
32+ if (current > 0) {
33+ body
3334 loop(current - 1)
3435 }
35- loop(x )
36+ loop(n )
3637 }
3738 }
3839 }
3940
40- This example creates the implicit class ` IntWithTimes ` . This class wraps an ` Int ` value and provides
41- a new method, ` times ` . To use this class, just import it into scope and call the ` times ` method.
42- Here's an example:
41+ This example creates the implicit class ` keep up with the times ` .
42+ The purpose of the funny name is to avoid name collisions.
43+ If it's desirable to avoid importing the implicit, then a conventional name
44+ such as ` IntWithTimes ` would enable an exclusionary import:
45+
46+ import Helpers.{IntWithTimes => _, _}
47+
48+ This class wraps an ` Int ` value and provides a new method, ` times ` .
49+ To use this class, just import it into scope and call the ` times ` method:
4350
4451 scala> import Helpers._
4552 import Helpers._
4653
47- scala> 5 times println("HI ")
48- HI
49- HI
50- HI
51- HI
52- HI
54+ scala> 5 times println("hello, world ")
55+ hello, world
56+ hello, world
57+ hello, world
58+ hello, world
59+ hello, world
5360
5461For an implicit class to work, its name must be in scope and unambiguous, like any other implicit
55- value or conversion.
62+ value or conversion. The important consideration is that the implicit class definition
63+ also introduces a method with the same name and parameters as the class. That method just
64+ forwards to the class constructor. A user-defined method with the same name and parameters would result
65+ in a compilation error.
66+
67+ The usual rules for implicit resolution apply:
68+
69+ trait T
5670
71+ object T {
72+ implicit class `t can f`(t: T) {
73+ def f = 42
74+ }
75+ }
76+
77+ object Test extends App {
78+ val t = null.asInstanceOf[T]
79+ println(t.f)
80+ }
5781
5882## Restrictions
5983
@@ -80,14 +104,16 @@ While it's possible to create an implicit class with more than one non-implicit
80104aren't used during implicit lookup.
81105
82106
83- ** 3. There may not be any method, member or object in scope with the same name as the implicit class .**
107+ ** 3. The ` implicit def ` introduced by ` implicit class ` must not be ambiguous with respect to other term members .**
84108
85- * Note: This means an implicit class cannot be a case class* .
109+ * Note: This means an implicit class cannot be a case class* . The reason for this restriction is shown below.
110+ In particular, ` Baz(42) ` is ambiguous because it means both the method ` Baz ` and the companion ` Baz.apply(42) ` .
111+ Therefore, ` implicit case class ` is outlawed outright.
86112
87113 object Bar
88- implicit class Bar(x: Int) // BAD!
114+ implicit class Bar(x: Int) // BAD! in local scope, there is no overloading
89115
90116 val x = 5
91- implicit class x(y: Int) // BAD!
117+ implicit class x(y: Int) // BAD! in local scope, there is no overloading
92118
93- implicit case class Baz(x: Int) // BAD!
119+ implicit case class Baz(x: Int) // BAD! the companion apply and implicit def are ambiguous together
0 commit comments