Я полагаю, что вы столкнулись с проблемой стертых зависимых от пути типов (см. Также Редактирование 2 ниже).
Давайте сначала упростим пример:
object Enum1 extends Enumeration {
val A, B = Value
}
object Enum2 extends Enumeration {
val C, D = Value
}
def t(x : Any) {
println(x match {
case ab : Enum1.Value => "from first enum"
case cd : Enum2.Value => "from second enum"
case _ => "other"
})
}
Теперь, подобно тому, что вы наблюдали, t(Enum1.A)
и t(Enum2.C)
оба печатают "from first enum"
.
То, что - я первоначально думал (см. Правку ниже) - происходит здесь, - то, что тест instanceOf
, который получается в результате использования :
в шаблоне, не делает различий между двумя зависимыми от пути экземплярами Value
, поэтому первый случай всегда совпадает.
Одним из способов решения этой проблемы является сопоставление значений перечисления вместо type следующих значений:
def t2(x : Any) {
println(x match {
case Enum1.A | Enum1.B => "from first enum"
case Enum2.C | Enum2.D => "from second enum"
case _ => "other"
})
}
<ч />
Edit 1 На самом деле моя гипотеза не соответствует тому, что говорит spec . Согласно спецификации языка (§8.2 Типовые шаблоны):
Типовые шаблоны состоят из типов, переменных типов и подстановочных знаков. Тип
шаблон T имеет одну из следующих форм:
- Ссылка на класс C, p.C или T #C. Этот тип шаблона соответствует любому ненулевому экземпляру данного класса. Обратите внимание, что префикс
класса, если он указан, имеет значение для определения класса
экземпляров. Например, шаблон p.C соответствует только экземплярам
классы C, которые были созданы с путем p как префикс. Дно
типы scala.Nothing и scala.Null нельзя использовать в качестве шаблонов типов,
потому что в любом случае они ничего не будут соответствовать.
- [...]
Если я правильно понимаю, instanceOf
или эквивалентный должен различать два случая.
<ч />
Редактировать 2 Кажется, это следствие этой проблемы .