Предупреждения являются правильными и ожидаемыми, поскольку, если смотреть изнутри foo
, Y
и Z
будут стерты до предела, т.е.X
.
Что более удивительно, так это то, что наличие либо совпадения с Y
, либо совпадения с Z
нарушает совпадение с X
, т.е.в этом случае
def foo(t: Module)(x: t.X): Unit = {
import t._
// the output depends on the order of the first 3 lines
// I'm not sure what's happening here...
x match {
// unchecked since it is eliminated by erasure
// case Y(_y) => println("y "+_y)
// unchecked since it is eliminated by erasure
// case Z(_z) => println("z "+_z)
// this one is fine
case X(_x) => println("x "+_x)
case xyz => println("xyz "+xyz)
}
}
результат равен
x 42
x 42
x 42
, что представляется разумным, тогда как при восстановлении одного из более ранних совпадений
def foo(t: Module)(x: t.X): Unit = {
import t._
// the output depends on the order of the first 3 lines
// I'm not sure what's happening here...
x match {
// unchecked since it is eliminated by erasure
case Y(_y) => println("y "+_y)
// unchecked since it is eliminated by erasure
// case Z(_z) => println("z "+_z)
// this one is fine
case X(_x) => println("x "+_x)
case xyz => println("xyz "+xyz)
}
}
результат
xyz AbstractMatch$ConcreteModule$X$$anon$1@3b58fa97
y AbstractMatch$ConcreteModule$X$$anon$1@3b58fa97
xyz Z(Y(AbstractMatch$ConcreteModule$X$$anon$1@3b58fa97))
, что не означает: я не вижу веских причин, по которым дополнительный случай может привести к выбору xyz
вместо X
, поэтому я думаю, что вы столкнулись сошибка в шаблоне соответствия.Я предлагаю вам поискать в Scala JIRA аналогичные проблемы, и если вы не можете их найти, откройте заявку с минимизированным примером воспроизведения, извлеченным из приведенного выше.
Если честно, во втором примере выше я хотел бымы ожидали, что регистр Y
будет выбран во всех трех случаях благодаря стиранию Y
в X
и регистру Y
, предшествующему регистру X
в выражении соответствия.Но мы здесь на неконтролируемой территории, и я не на 100% уверен в своей интуиции.