2010-08-25 211 views
6

任何人都可以啓發我爲什麼隱式類型轉換不適用於==斯卡拉隱式類型轉換和==

例子:

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) 
} 

現在我可以這樣做:

scala> BitArray(5) + 5 
res13: BitArray = 00000000000000000000000000001010 
scala> 5 + BitArray(5) 
res14: BitArray = 00000000000000000000000000001010 
scala> BitArray(5) == 5 
res15: Boolean = true 
scala> BitArray(5) == 6 
res16: Boolean = false 

但是:

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 

回答

12

你錯過了Scala的一個基本方面,這就是平等的工作原理。

基本上,延長AnyRef所有類都實現了以下方法:

def equals (arg0: Any) : Boolean 

和所有類都實現了以下方法:

def == (arg0: Any) : Boolean 

現在,你應該重寫不==,但equals。方法==將調用equals,但Java代碼將使用equals而不是==。這不是你所看到的問題的原因,但是我認爲這很重要,值得一提。

現在,對於隱式不工作,請記住,只有在沒有方法滿足您的代碼時纔會查找implicint。但是,Int==可以與BitArray進行比較,因爲==接收到類型爲Any的參數。因此,Int的平等方法被調用,並且沒有隱式被查找。

+0

非常明確的答案感謝:-) – 2010-08-25 13:26:10

+1

不是Scala的基本方面,而是標準庫如何從根本上打破的一個方面。 – Apocalisp 2010-08-25 14:32:37

+2

@Apocalisp我的意思是基本的,如「你必須知道這一點,如果你想使用斯卡拉」。 – 2010-08-25 18:08:21

6

要覆蓋==操作,你實際上應該重寫equals方法:

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

您不能使您的BitArray的實例等於Long並仍然服從等價合約(即,它不會是對稱的)。

+0

你能詳細點嗎?或者指出一些關於平等運作的文件的方向? 謝謝 – 2010-08-25 13:20:49

0

添加到其他答案,記住等功能必須是SYMMETRIC,即(a equals b) == (b equals a)