문제

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 ?
도움이 되었습니까?

해결책

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top