开发者

Scala implicit type conversion and ==

开发者 https://www.devze.com 2023-01-13 15:31 出处:网络
Can anyone enlighten me as to why implicit type conversion does not work with ==? Example: class BitArray(l: Int, v: Long) {

Can anyone enlighten me as to why implicit type conversion does not work with ==?

Example:

class BitArray(l: Int, v: Long) {  
    val length = l  
    var value = v  
    def ==(that: BitArray) = value == that.value  
    def ==(integer: Long) = value == integer  
    def +(that: BitArray) = new BitArray(length,value+that.value )  
    def +(integer: Long) = new BitArray(length,value+integer )  
//...  
}  
object BitArray{
        implicit def longToBitArray(x : Long) = new BitArray(64,x)  
        def apply(v: Long) :BitArray = apply(64,v)  
}

Now I can do:

scala> BitArray(5) + 5  
res13: BitArray = 0000000000000000开发者_C百科0000000000001010  
scala> 5 + BitArray(5)   
res14: BitArray = 00000000000000000000000000001010  
scala> BitArray(5) == 5  
res15: Boolean = true  
scala> BitArray(5) == 6  
res16: Boolean = false  

BUT:

scala> 5 == BitArray(5)  
<console>:11: warning: comparing values of types Int and BitArray using `==' will   
always yield false  
       5 == BitArray(5)  
         ^  
res17: Boolean = false  


You are missing a fundamental aspect of Scala, which is how equality works.

Basically, all classes extending AnyRef implement the following method:

def   equals  (arg0: Any)  : Boolean   

And all classes implement the following method:

def   ==  (arg0: Any)  : Boolean

Now, you should override not ==, but equals. The method == will call equals, but Java code will use equals, not ==. This is not the cause of the problem you see, but it is important enough that I think it is worth mentioning.

Now, as to the implicit not working, remember that implicits are only looked for if there is no method that satisfy your code. However, Int's == can be compared with BitArray, as == receives an argument of type Any. Therefore, Int's equality method is called, and no implicit is looked for.


To override the == operator, you should actually override the equals method:

override def equals(other: Any): Boolean = other match {
  case ba: BitArray => value == ba.value
  case _ => false
}

You can't make an instance of your BitArray equal to a Long and still obey the equals contract (ie. it won't be symmetric).


Adding to the other answers, remember that the equals function has to be SYMMETRIC, that is (a equals b) == (b equals a).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号