Frage

I have:

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 ?
War es hilfreich?

Lösung

You should not create your own == method. In scala == method is implemented using 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
//                       ^       

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 method signature is 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

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top