类型边界意外地更改了Scala隐式参数解析的优先级

时间:2013-04-06 14:44:33

标签: scala implicit

下面的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)
}

请注意,隐式方法ab之间的唯一区别是类型边界,并且它们都可以匹配TC[C]。如果删除方法b,则会隐式解析a

虽然我在实践中发现这种行为很方便,但我想了解它是指定的语言功能,还是只是一个实现怪癖。

编译器是否优先考虑b优先于a的语言规则或原则,而不是将它们视为等效且因此含糊不清的选项?

1 个答案:

答案 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的类的伴随对象。
  •