Ошибка нижних границ Scala: значение не является членом параметра типа - PullRequest
0 голосов
/ 09 декабря 2018

Компилятор scala, похоже, выдает ложные ошибки типа для операторов с несколькими нижними границами.

Для данного класса Foo с методом g используется нижняя граница для A и B

class Foo[A, B](a: A, b: B) {
  def g[T, A1 >: A <: T, B1 >: B <: T] = List[T](a: A1, b: B1)
}

из https://stackoverflow.com/a/6124549, и классов X, Y <: X и Z <: X,

abstract class X {def a: String}
object Y extends X {def a = "this is Y"}
object Z extends X {def a = "this is Z"}

следующий код работает нормально, как и ожидалось:

Y.a
new Foo(Y,Z).g
new Foo(Y,Z).g.head // instance of Y, type X
new Foo(Y,Z).g.head.isInstanceOf[X] // true
new Foo(Y,Z).g.head.asInstanceOf[X].a
new Foo(Y,Z).g[X,Y.type,Z.type].head.a
new Foo(Y,Z).g[X,X,X].head.a
{val y = new Foo(Y,Z).g.head; y}.a

Удивительно, но

new Foo(Y,Z).g.head.a

делает не !(протестировано в Scala 2.12.7, 2.12.8, 2.13.0-M5, но в Dotty работает должным образом)

Это дает error: value a is not a member of type parameter T.

Это ошибка вкомпилятор или есть конкретная причина, почему я не могу вызвать a на new Foo(Y,Z).g.head?

y получает тип X, поэтому компилятор может , очевидно, выяснитьчто new Foo(Y,Z).g.head имеет тип X, и я не понимаю, зачем присваивать его новому значению и вызывать метод, который помогает проверять тип.Кроме того, я думаю, что явное приведение к X не должно ничего менять, но это действительно так.

Попробуйте онлайн!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...