Почему неявный объект имеет приоритет над val в Scala 2.13-M5?
Мне интересно, является ли это ошибкой или ожидаемым поведением в 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]
1 ответ
В вашем примере a
, b
а также f
все кажутся приемлемыми неявными значениями. Как говорится в FAQ (выделено мое):
[...] это влечет за собой выбор более узкого типа или значения, определенного в подклассе, относительно других допустимых значений
следовательно, объект 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"
, потому что экземпляр класса MoreSpecial
считает, что это самый конкретный, просто потому, что его тип MoreSpecial
это строгий подтип TS
,
Более того,
- если вы раскомментируете
b
линия, это дает неоднозначную ошибку следствий (b: b.type <: TS
конфликтует сs: MoreSpecial <: TS
) - если вы прокомментируете
s
линия, это также дает неоднозначную ошибку следствий (a: TS
конфликтует сf: TS
) - только если ((
s
комментируется) XOR (b
комментируется)), затем компилируется (обаb: b.type
а такжеs: MoreSpecial
побеждатьa: TS
а такжеf: TS
)
Это все как и ожидалось. Это относится к 2.12.6, поэтому он не кажется специфичным для 2.13-Mx.