说我有以下内容:
class A {
def foo() = { println("foo") }
}
case class B(a: A)
implicit def toA(b: B) = b.a
implicit def wrapper(a: A) = new {
def bar() = a.foo()
}
然后我不能做以下事情:
val b = B(new A())
b.bar() // cannot resolve
相反,我需要显式调用toA()隐式:
toA(b).bar()
或者做
(b: A).bar()
为什么编译器在应用第二个隐式包装器之前不知道应用第一个隐式?
一次一个规则:只尝试一个隐式。编译器永远不会将
x + y
重写为convert1(convert2(x)) + y
。这样做会导致编译时间在错误的代码上急剧增加,并且会增加程序员编写的内容与程序实际执行的内容之间的差异。出于理智的考虑,当编译器已经在尝试另一个隐式转换时,编译器不会插入进一步的隐式转换。但是,可以通过隐含参数来避免这种限制,这将在本章后面介绍。
部分21.2 Rules for implicits,来自Scala编程,First Edition,Martin Odersky,Lex Spoon和Bill Venners。