This topic provides some explanation about how implicit parameters are resulted. There are very strict rules for which implicit value is to be applied to a implicit parameter. A simple way to think about it is that the "closest" definition will be used. Local scope, enclosing class, parent class, companion object of the desired type.
- class X(val i:Int)
 - class Y(val i:Int)
 - object X {
 -   implicit def xx = new X(1)
 - }
 - class Method {
 -   def x(implicit x:X)=println(x.i)
 -   def y(implicit y:Y)=println(y.i)
 - }
 - trait M { 
 -   self : Method =>
 -   implicit def x1 = new X(10)
 -   implicit def y1 = new Y(100)
 -   def testy = y
 -   def testx = x
 - }
 - trait SM extends M {
 -   self : Method =>
 -   implicit def x2 = new X(20)
 -   implicit def y2 = new Y(200)
 -   
 -   def testy2 = y  
 - }
 - // implicit resolved from companion object of X
 - new Method().x
 - // explicit applied so that value is used
 - new Method().x(new X(3))
 - // implicit resolved from companion object of X
 - // NOT from M.  This is because the call site of x 
 - // is not within M therefore does not use the implicits in M
 - // for resolution.
 - (new Method with M).x
 - implicit def x = new X(30)
 - // local scope overrides companion object implicit
 - new Method().x
 - // explicit applied so that value is used
 - new Method().x(new X(3))
 - // local scope overrides companion object implicit
 - (new Method with M).x
 - // testy is defined within M so the implicits within M
 - (new Method with M).testy
 - // testx is defined within M so the implicit within M
 - // overrides the companion object implicit
 - (new Method with M).testx
 - // testy is within M (not SM) so the implicit within M
 - // is used
 - (new Method with SM).testy
 - // testy2 is within SM so the implicit within SM 
 - // overrides the implicit in M and the companion object
 - (new Method with SM).testy2
 
Output:
1
3
1
30
3
30
100
10
100
200
# // testy is within M not SM so the implicit within SM
ReplyDelete# // is used
Should it be:
# // testy is within M not SM so the implicit within M
# // is used
?