在Scala中,我有一个表示一些数据的案例类:
case class Foo( val start : Int, val end : Int )
我经常使用复制方法。
但是,我现在已经达到了我想添加额外成员作为标识符的程度,因为我想要以下等式行为:
case class NewFoo( val id : Int, val start : Int, val end : Int )
{
override def equals( any : Any ) = any match
{
case other : NewFoo => id == other.id
case _ => false
}
}
但是,我现在想要阻止用户在复制id
实例时更改NewFoo
,因此,一旦创建NewFoo
,其数据就会发生变化,但是它的id
将始终保持不变。
这种情况可以用于案例类吗?我怀疑不是,因为它不是真正的设计目标。另一方面,我读过的关于case类的定义是它们是“普通且不可变的数据保持对象,应该完全取决于它们的构造函数参数”,这个定义似乎没有被我的用例打破
如果案例类不合适,有没有办法可以复制一个案例的功能,特别是复制方法,而没有明确的案例类?我没有使用模式匹配。
答案 0 :(得分:4)
是的,你可以像这样手动实现copy
方法:
sealed class NewFoo(val id: Int, val start: Int, val end: Int) {
def copy(start: Int = start, end: Int = end) = new NewFoo(id, start, end)
override def equals(any: Any) = any match {
case other : NewFoo => id == other.id
case _ => false
}
// don't forget to override `hashCode` with `equals`
override def hashCode() = id.hashCode()
}
请注意,您还应该使用hashCode
覆盖equals
。
您还可以让您的课程sealed
避免此equals
实施的问题。
另见Programming in Scala/Object Equality。
您还可以使用此随播对象实现保存模式匹配和实例创建,而不使用new
(NewFoo(0, 0, 0)
):
object NewFoo {
def apply(id: Int, start: Int, end: Int) = new NewFoo(id, start, end)
def unapply(f: NewFoo): Option[(Int, Int, Int)] = Some((f.id, f.start, f.end))
}