为什么 Scala 的编译器不能使用继承类型的隐式转换?

Why Scala's compiler is not able to use an implicit conversion of an inherited type?

我目前正在深入研究隐含的主题,并被这个案例困住了:

class A
class B extends A

object A { implicit def b2String(b: B): String = "B" }
object B { implicit def a2String(a: A): String = "A" }

val s: String = new B // This does not compile

我知道这有点极端,但我想了解它。编译器不应该选择 A 的 implicit (b2String) 吗?还是(看起来)它坚持最具体类型的伴生对象 (B)?这是否意味着继承类型的伴随对象隐式不被继承?

提前致谢。

编辑: 如果A的伴随对象被删除,那么它编译并且s的值为"A"。所以编译器能够弄清楚对 A 的隐式有效也对 B 有效。

编辑: 如果我进行以下更改,这也会编译:

  class A
  class B extends A

  object A { implicit def b2String(b: B): Int = 1 }
  object B { implicit def a2String(a: A): String = "A" }

  val s: String = new B
  val i: Int = new B

所以伴随对象隐式是继承的。

它无法编译,因为有两个可用的隐式,并且根据 http://scala-lang.org/files/archive/spec/2.11/06-expressions.html#overloading-resolution 中的规则,它们具有相同的相对权重:b2Stringa2String 多 1,因为它在派生 class 的伴生对象,并且 a2Stringb2String 多 1,因为它更具体。