【问题标题】:Type bounds unexpectedly change precedence of Scala implicit parameter resolution类型边界意外改变了 Scala 隐式参数解析的优先级
【发布时间】:2013-04-06 14:44:33
【问题描述】:

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

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

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

是否存在编译器优先考虑b 而不是a 的语言规则或原则,而不是将它们视为等价的因此模棱两可的选项?

【问题讨论】:

    标签: scala implicit


    【解决方案1】:

    有一条关于此优先级的规则,即两个匹配项中最具体的一个将获得更高的优先级。来自Scala Reference,在 6.26.3 '重载分辨率'下:

    备选方案 A 相对备选方案 B 的相对权重是一个从 0 到 2 的数字,定义为以下各项的总和

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

    一个类或对象 C 是从一个类或对象 D 派生的,如果其中一个 以下保持:

    • C 是 D 的子类,或
    • C 是从 D 派生的类的伴生对象,或
    • D 是派生出 C 的类的伴随对象。

    【讨论】:

    • SLS 是否直接说明类型参数的界限?换句话说,“A 与 B 一样具体”的技术含义是什么?
    • 我认为它只讨论了一般的选择替代方案,在 <: bounds b>
    猜你喜欢
    • 2012-01-27
    • 1970-01-01
    • 2020-11-05
    • 2021-09-03
    • 1970-01-01
    • 2016-08-24
    • 1970-01-01
    • 2020-07-06
    • 1970-01-01
    相关资源
    最近更新 更多