У меня есть класс, который сериализуется и десериализуется в сеансе, и мне нужно выполнить сопоставление с образцом для внутренних классов. У меня проблемы с идентичностью внутренних классов:
class Tree(val id: Int) {
override def hashCode = id
override def equals(that: Any) = that.isInstanceOf[Tree] &&
that.asInstanceOf[Tree].id == id
case object EmptyValue
}
val t1 = new Tree(33)
val t2 = new Tree(33)
t1 == t2 // ok
t1.EmptyValue == t2.EmptyValue // wrong -- reports 'false'
Какой элегантный способ исправить идентификатор для EmptyValue
, чтобы он не назывался, так сказать, «зависимостью от пути выхода». У меня есть код, подобный следующему, который ломается, когда происходит сериализация:
def insert(point: Point, leaf: Leaf): Unit = {
val qidx = hyperCube.indexOf(point)
child(qidx) match {
case EmptyValue => ...
...
}
}
То есть, хотя компилятор говорит, что мое совпадение является исчерпывающим , я получаю время выполнения MatchError
при использовании сериализации (у меня есть специальный код, который записывает / читает из байтовых массивов). Например, я звоню из дерева с Tree$EmptyValue$@4636
и получаю Tree$EmptyValue$@3601
, и они не совпадают.
EDIT
Я провел дополнительные тесты, потому что я действительно хотел бы избежать перемещения внутренних типов, так как они должны будут иметь параметры типа и таким образом нарушать весь код сопоставления с образцом. Похоже, что проблема возникает только с этим конкретным case object
:
class Tree {
sealed trait LeftChild
case object EmptyValue extends LeftChild
sealed trait LeftNonEmpty extends LeftChild
final case class LeftChildBranch() extends LeftNonEmpty
def testMatch1(l: LeftChild) = l match {
case EmptyValue => "empty"
case LeftChildBranch() => "non-empty"
}
def testMatch2(l: LeftChild) = l match {
case EmptyValue => "empty"
case n: LeftNonEmpty => "non-empty"
}
}
val t1 = new Tree
val t2 = new Tree
t1.testMatch1(t2.LeftChildBranch().asInstanceOf[t1.LeftChild]) // works!!!
t1.testMatch2(t2.LeftChildBranch().asInstanceOf[t1.LeftChild]) // works!!!
t1.testMatch1(t2.EmptyValue.asInstanceOf [t1.EmptyValue.type]) // fails