Scala 为什么可以';嵌入隐式调用

Scala 为什么可以';嵌入隐式调用,scala,implicit-conversion,implicit,Scala,Implicit Conversion,Implicit,假设我有以下几点: 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 那么我不能做以下事情: class A { def foo(

假设我有以下几点:

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
那么我不能做以下事情:

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()
或者

为什么编译器在应用第二个隐式包装器之前不知道应用第一个隐式包装器

一次一个规则:只尝试一个隐式。编译器永远不会将
x+y
重写为
convert1(convert2(x))+y
。这样做会导致错误代码的编译时间急剧增加,并且会增加程序员编写的代码与程序实际执行的代码之间的差异。出于理智的考虑,当编译器已经尝试了另一个隐式时,编译器不会插入其他隐式转换。但是,可以通过让隐式函数接受隐式参数来绕过此限制,这将在本章后面介绍

第节,来自Scala编程, 作者:马丁·奥德斯基、莱克斯·斯彭和比尔·维纳斯

一次一个规则:只尝试一个隐式。编译器永远不会将
x+y
重写为
convert1(convert2(x))+y
。这样做会导致错误代码的编译时间急剧增加,并且会增加程序员编写的代码与程序实际执行的代码之间的差异。出于理智的考虑,当编译器已经尝试了另一个隐式时,编译器不会插入其他隐式转换。但是,可以通过让隐式函数接受隐式参数来绕过此限制,这将在本章后面介绍

第节,来自Scala编程,
马丁·奥德斯基、莱克斯·斯彭和比尔·维纳斯所著。

这需要两个隐含的解决方案。我猜编译器只是在一次隐式解析后放弃了—如果它更努力,编译可能需要非常长的时间。此外,IMHO依赖于两个隐式使得代码很难推理,隐式转换本身也被认为是一种不好的做法。为什么不直接将扩展方法
foo
添加到
B
?不幸的是,我的场景不允许对B进行修改-这是我可以做的最简单的例子。我的意思是
隐式类BOP(val B:B)扩展AnyVal{def foo():=B.a.bar()}
。这需要两个隐式解析。我猜编译器只是在一次隐式解析后放弃了—如果它更努力,编译可能需要非常长的时间。此外,IMHO依赖于两个隐式使得代码很难推理,隐式转换本身也被认为是一种不好的做法。为什么不直接将扩展方法
foo
添加到
B
?不幸的是,我的场景不允许对B进行修改-这是我可以做的最简单的例子。我的意思是
隐式类BOP(val B:B)扩展AnyVal{def foo():=B.a.bar()