Почему неявный объект имеет приоритет над val в Scala 2.13-M5? - PullRequest
0 голосов
/ 30 августа 2018

Мне интересно, это ошибка или ожидаемое поведение в 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 Ответ

0 голосов
/ 30 августа 2018

В вашем примере 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.

* 1 028 * Кроме того, * * тысяча двадцать-девять
  • если вы раскомментируете строку 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.

...