2010-08-25 202 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)