首页 > 解决方案 > 为什么隐式对象在 Scala 2.13-M5 中优先于 val?

问题描述

我想知道这是 Scala 2.13-M5 中的错误还是预期行为。

以下代码段编译并输出“包对象中的对象”:

package object test {
  implicit val a: TS = new TS("val in package object")
  implicit object b extends TS("object in package object")
}

package test {
  class TS(override val toString: String)

  class Inner {
    implicit val f: TS = new TS("val in inner class")
    val resolve = implicitly[TS]
  }
  object Test extends App {
    println(new Inner().resolve)
  }
}

注释掉第三行后implicit object b extends TS("object in package object",会出现一个模棱两可的隐式编译错误,这也是我在第一种情况下所期望的:

Error:(11, 29) ambiguous implicit values:
 both value a in package test of type => test.TS
 and value f in class Inner of type => test.TS
 match expected type test.TS
    val resolve = implicitly[TS]

标签: scalaresolutionimplicitscala-2.13

解决方案


在您的示例中abfall 似乎都是合格的隐式值。正如常见问题解答所说(强调我的):

[...] 这需要选择相对于其他符合条件的值在子类中定义的更窄类型或值

因此,该对象b被选中,因为b.type它是 的严格子类型TS


这是另一个演示相同行为的示例,但没有包或对象:

case class TS(str: String)

object test {
  implicit val a: TS = new TS("val in package object")
  // implicit object b extends TS("object in package object")
  class MoreSpecial() extends TS("I'm special")
  implicit val s: MoreSpecial = new MoreSpecial()

  class TS(override val toString: String)

  class Inner {
    implicit val f: TS = new TS("val in inner class")
    val resolve = implicitly[TS]
  }
  object Test {
    def run(): Unit = {
      println(new Inner().resolve)
    }
  }
}

test.Test.run()

它将打印"I'm special",因为 class 的实例MoreSpecial认为它是最具体的,仅仅是因为它的类型MoreSpecial是 的严格子类型TS

而且,

  • 如果您取消注释该b行,它会给出模棱两可的隐含错误(b: b.type <: TS与 冲突s: MoreSpecial <: TS
  • 如果您评论该s行,它也会给出模棱两可的隐含错误(a: TS与 冲突f: TS
  • 仅当 ((s已注释) XOR (b已注释)) 时,它才会编译(两者都b: b.types: MoreSpecial胜过a: TSand f: TS

这一切都在意料之中。这适用于 2.12.6,因此它似乎并不特定于 2.13-Mx。


推荐阅读