隐式解析中的 Scala 类型约束优先级



我有这两个隐式

trait A[T] {
val name: String
}
trait B
object A {
implicit def product[T <: Product] = new A[T] {
override val name: String = "product"
}
implicit def childOfB[T <: Product with B] = new A[T] {
override val name: String = "child of B"
}
}

如果我试图找到A[C]的隐式实例,C在哪里

case class C() extends B

childOfB将被选中。

我知道这是合乎逻辑的,但为什么会发生这种情况?我在任何地方都找不到记录。

Scala 语言规范 说:

如果有几个符合条件的参数与隐式参数匹配 参数的类型,将使用规则选择最具体的类型 静态重载分辨率。

重载分辨率的概念是一个符号比其他符号更具体。特异性的精确、一般定义非常复杂(如您在上面链接的规范中看到的那样(,但在您的情况下,它归结为这样一个事实,即childOfB严格涵盖了product所涵盖的类型子集,因此更具体

规范说

如果有几个符合条件的参数与隐式参数匹配 参数的类型,将使用规则选择最具体的类型 静态重载分辨率。

为了扩展@ghik的答案,从Scala 中的编程

准确地说,如果以下情况之一适用,则一个隐式转换比另一个隐式转换更具体

  • 前者的论点是后者的子类型
  • 两种转换都是方法,前者的封闭类扩展了后者的封闭类

我的猜测是,该引用中的"参数"也指类型参数,正如所指出的那样。

object A {
implicit def A2Z[T <: A] = new Z[T] {println("A")}
implicit def B2Z[T <: B] = new Z[T] {println("B")}
}
trait A
trait B extends A
trait Z[T]
def aMethod[T <: A](implicit o: Z[T]) = ()
implicit val a: A = new A {}
aMethod // prints B even though we started with an A

最新更新