隐式解析中的 Scala 类型约束优先级
Scala type constraint precedence in implicit resolution
我有这两个隐式
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
将被选中。
我知道这是合乎逻辑的,但为什么会这样?我在任何地方都找不到它的记录。
规格says
If there are several eligible arguments which match the implicit
parameter's type, a most specific one will be chosen using the rules
of static overloading resolution.
Scala Language Specification 说:
If there are several eligible arguments which match the implicit
parameter's type, a most specific one will be chosen using the rules
of static overloading resolution.
重载解析的概念是一个符号比其他符号更具体。精确性的一般定义非常复杂(正如您在上面链接的规范中看到的那样),但在您的情况下,它归结为 childOfB
严格涵盖 product
和因此更具体。
要扩展@ghik 的回答,来自 Programming in Scala、
To be more precise, one implicit conversion is more specific than another if one of the following applies:
- The argument of the former is a subtype of the latter's
- Both conversions are methods, and the enclosing class of the former extends the enclosing class of the latter
我的猜测是 "argument" 在该引用中也指类型参数,正如
所建议的那样
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
我有这两个隐式
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
将被选中。
我知道这是合乎逻辑的,但为什么会这样?我在任何地方都找不到它的记录。
规格says
If there are several eligible arguments which match the implicit parameter's type, a most specific one will be chosen using the rules of static overloading resolution.
Scala Language Specification 说:
If there are several eligible arguments which match the implicit parameter's type, a most specific one will be chosen using the rules of static overloading resolution.
重载解析的概念是一个符号比其他符号更具体。精确性的一般定义非常复杂(正如您在上面链接的规范中看到的那样),但在您的情况下,它归结为 childOfB
严格涵盖 product
和因此更具体。
要扩展@ghik 的回答,来自 Programming in Scala、
To be more precise, one implicit conversion is more specific than another if one of the following applies:
- The argument of the former is a subtype of the latter's
- Both conversions are methods, and the enclosing class of the former extends the enclosing class of the latter
我的猜测是 "argument" 在该引用中也指类型参数,正如
所建议的那样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