4

下面的 Scala 示例显示了一种情况,其中所需的隐式参数(类型TC[C])可以由范围内的隐式方法ab. 但是在运行时,不会产生歧义,并且会打印“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,而不是将它们视为等效且因此模棱两可的选项?

4

1 回答 1

3

有一条关于此优先级的规则,即两场比赛中最具体的一场将获得更高的优先级。来自Scala Reference,在 6.26.3 'Overloading Resolution' 下:

备选方案 A 相对于备选方案 B 的相对权重是一个从 0 到 2 的数字,定义为

  • 如果 A 与 B 一样具体,则为 1,否则为 0,并且
  • 如果 A 在派生自定义 B 的类或对象的类或对象中定义,则为 1,否则为 0。

如果满足以下条件之一,则类或对象 C 派生自类或对象 D:

  • C 是 D 的子类,或
  • C 是从 D 派生的类的伴随对象,或
  • D 是派生 C 的类的伴生对象。
于 2013-04-06T15:00:22.627 回答