我有这两个隐式
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
将被选择。
我知道这是合乎逻辑的,但是为什么会这样呢?我找不到任何地方的文件。
答案 0 :(得分:4)
Scala Language Specification说:
如果有几个与隐式匹配的合格参数 参数的类型,将使用规则选择最具体的类型 静态overloading resolution。
重载分辨率的概念是,一个符号比另一个符号更具体。精确的通用通用定义非常复杂(如您在上面的链接说明中所见),但是在您的情况下,可以归结为以下事实:childOfB
严格覆盖了product
和因此是更具体。
答案 1 :(得分:2)
规范says
如果有几个与隐式匹配的合格参数 参数的类型,将使用规则选择最具体的类型 静态overloading resolution。
答案 2 :(得分:2)
要扩展@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