下面的Scala示例显示了范围TC[C]
和a
中隐式方法可以提供所需隐式参数(类型为b
)的情况。但是在运行时,不会产生歧义,并打印出“B”。
object Example extends App{
trait A
trait B extends A
class C extends B
class TC[X](val label: String)
implicit def a[T <: A]: TC[T] = new TC[T]("A")
implicit def b[T <: B]: TC[T] = new TC[T]("B")
println(implicitly[TC[C]].label)
}
请注意,隐式方法a
和b
之间的唯一区别是类型边界,并且它们都可以匹配TC[C]
。如果删除方法b
,则会隐式解析a
。
虽然我在实践中发现这种行为很方便,但我想了解它是指定的语言功能,还是只是一个实现怪癖。
编译器是否优先考虑b
优先于a
的语言规则或原则,而不是将它们视为等效且因此含糊不清的选项?
答案 0 :(得分:3)
有一个关于此优先级的规则,它表示两个匹配中最具体的优先级将获得更高的优先级。来自Scala Reference,在6.26.3'重载决议'下:
备选方案A相对于备选方案B的相对权重是从0到2的数字,定义为
的总和
- 1如果A特定于B,则0,否则
- 1如果A在类或对象中定义,该类或对象派生自定义B的类或对象,否则为0。
类或对象C派生自类或对象D(如果其中之一) 以下是:
- C是D的子类,或
- C是从D或
派生的类的伴随对象- D是派生C的类的伴随对象。