为什么隐式对象在 Scala 2.13-M5 中优先于 val?
Why implicit object has precedence over val in Scala 2.13-M5?
我想知道这是 Scala 2.13-M5 中的错误还是预期行为。
以下代码片段编译并输出 "object in package object":
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]
在您的示例中,a
、b
和 f
似乎都是符合条件的隐式值。正如 FAQ 所说(强调我的):
[...] this entails selecting a narrower type or a value defined in a subclass relative to other eligible values
因此,对象 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
是 MoreSpecial
的严格子类型TS
.
此外,
- 如果您取消注释
b
行,它会给出不明确的隐式错误(b: b.type <: TS
与 s: MoreSpecial <: TS
冲突)
- 如果您注释
s
行,它还会给出模糊的隐式错误(a: TS
与 f: TS
冲突)
- only if ((
s
is commented) XOR (b
is commented)), then it compiles (both b: b.type
and s: MoreSpecial
win over a: TS
和 f: TS
)
这一切都符合预期。这适用于 2.12.6,因此它似乎并不特定于 2.13-Mx。
我想知道这是 Scala 2.13-M5 中的错误还是预期行为。
以下代码片段编译并输出 "object in package object":
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]
在您的示例中,a
、b
和 f
似乎都是符合条件的隐式值。正如 FAQ 所说(强调我的):
[...] this entails selecting a narrower type or a value defined in a subclass relative to other eligible values
因此,对象 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
是 MoreSpecial
的严格子类型TS
.
此外,
- 如果您取消注释
b
行,它会给出不明确的隐式错误(b: b.type <: TS
与s: MoreSpecial <: TS
冲突) - 如果您注释
s
行,它还会给出模糊的隐式错误(a: TS
与f: TS
冲突) - only if ((
s
is commented) XOR (b
is commented)), then it compiles (bothb: b.type
ands: MoreSpecial
win overa: TS
和f: TS
)
这一切都符合预期。这适用于 2.12.6,因此它似乎并不特定于 2.13-Mx。