Почему неявный объект имеет приоритет над 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.

Другие вопросы по тегам