平等和案例分类 [英] Equality and Case Classes
问题描述
我有:
sealed trait BEValue
case class BEByteString(val value: Array[Byte]) extends BEValue {
def equals(that: BEByteString): Boolean = this.value.deep == that.value.deep
def ==(that: BEByteString) = this equals that
}
case class BEList(val value: List[BEValue]) extends BEValue
BEByteString("spam".getBytes) == BEByteString("spam".getBytes) //true
val l1 = BEList(BEByteString("spam".getBytes):: Nil)
val l2 = BEList(BEByteString("spam".getBytes):: Nil)
l1 == l2 // false. Why ?
推荐答案
您不应创建自己的 ==
方法.在Scala中, ==
方法是使用 equals
来实现的.
You should not create your own ==
method. In scala ==
method is implemented using equals
.
您应该使用 override
关键字来覆盖 equals
方法.
You should use override
keyword to override equals
method.
case class BEByteString(val value: Array[Byte]) extends BEValue {
override def equals(that: BEByteString): Boolean = this.value.deep == that.value.deep
}
// <console>:11: error: method equals overrides nothing
// override def equals(that: BEByteString): Boolean = this.value.deep == that.value.deep
// ^
您已经创建了一个新的 equals
方法.而新的 ==
方法是使用新的 equals
方法实现的.但是case类的equals是使用 Any#equals
方法作为参数来实现的.
You have created a new equals
method. And your new ==
method is implemented using your new equals
method. But case class equals is implemented using Any#equals
method for parameters.
Any#equals
方法签名为 def equals(that:Any):Boolean
case class BEByteString(val value: Array[Byte]) extends BEValue {
override def equals(that: Any): Boolean = that match {
case BEByteString(thatValue) => thatValue.deep == this.value.deep
case _ => false
}
}
l1 == l2
// Boolean = true
请注意,您可以使用 IndexedSeq [Byte]
而不是 Array [Byte]
.在这种情况下,您可以使用默认的 equals
实现.这也使您的 BEByteString
类不可变:使用 Array [Byte]
可以更改 value
的内容.
Note that you could use IndexedSeq[Byte]
instead of Array[Byte]
. In this case you could use a default equals
implementation. It also makes your BEByteString
class immutable: with Array[Byte]
one can change a content of value
.
这篇关于平等和案例分类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!