为什么我不能嵌入隐式调用
Why can't I embed implicit calls
假设我有以下内容:
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()
为什么编译器不知道在应用第二个隐式包装器之前应用第一个隐式?
One-at-a-time Rule: Only one implicit is tried. The compiler will never rewrite x + y
to convert1(convert2(x)) + y
. Doing so would cause compile times to increase dramatically on erroneous code, and it would increase the difference between what the programmer writes and what the program actually does. For sanity's sake, the compiler does not insert further implicit conversions when it is already in the middle of trying another implicit. However, it's possible to circumvent this restriction by having implicits take implicit parameters, which will be described later in this chapter.
部分21.2 Rules for implicits, from Programming in Scala, First Edition
作者:Martin Odersky、Lex Spoon 和 Bill Venners。
假设我有以下内容:
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()
为什么编译器不知道在应用第二个隐式包装器之前应用第一个隐式?
One-at-a-time Rule: Only one implicit is tried. The compiler will never rewrite
x + y
toconvert1(convert2(x)) + y
. Doing so would cause compile times to increase dramatically on erroneous code, and it would increase the difference between what the programmer writes and what the program actually does. For sanity's sake, the compiler does not insert further implicit conversions when it is already in the middle of trying another implicit. However, it's possible to circumvent this restriction by having implicits take implicit parameters, which will be described later in this chapter.
部分21.2 Rules for implicits, from Programming in Scala, First Edition 作者:Martin Odersky、Lex Spoon 和 Bill Venners。