我有一个在会话中被序列化和反序列化的类,我需要对内部类执行模式匹配。我在内部类的身份方面遇到问题:
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
并检索 aTree$EmptyValue$@3601
并且它们不匹配。
编辑
我进行了进一步的测试,因为我真的很想避免将内部类型移出,因为它们需要具有类型参数,从而破坏所有模式匹配代码。看起来好像问题只发生在那个特定的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