平等和案例类

时间:2014-01-26 23:31:43

标签: scala equals case-class

我有:

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 ?

1 个答案:

答案 0 :(得分:4)

您不应该创建自己的==方法。在scala中==方法是使用equals实现的。

您应该使用override关键字来覆盖equals方法。

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方法实现的。但是使用Any#equals方法为参数实现了case class equals。

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的内容。