Может кто-нибудь просветить меня, почему неявное преобразование типов не работает с ==
?
Пример:
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
Вам не хватает фундаментального аспекта Scala, а именно принципа работы равенства.
По сути, все классы, расширяющие AnyRef
, реализуют следующий метод:
def equals (arg0: Any) : Boolean
И все классы реализуют следующий метод:
def == (arg0: Any) : Boolean
Теперь вы должны переопределить не ==
, а равно
. Метод ==
вызовет равно
, но код Java будет использовать равно
, а не ==
. Это не причина проблемы, которую вы видите, но она достаточно важна, и я думаю, что о ней стоит упомянуть.
Теперь, что касается неявного неработающего, помните, что имплициты ищутся только в том случае, если нет метода, удовлетворяющего вашему коду. Однако Int
==
можно сравнить с BitArray
, поскольку ==
получает аргумент типа Any
. Поэтому вызывается метод равенства Int
, и неявный поиск не выполняется.
Чтобы переопределить оператор ==
, вы должны фактически переопределить метод равно
:
override def equals(other: Any): Boolean = other match {
case ba: BitArray => value == ba.value
case _ => false
}
Вы не можете создать экземпляр своего BitArray
равняется Long
и по-прежнему подчиняется контракту равенства (т. Е. Не будет симметричным).