Scala, Java и равенство - PullRequest
       45

Scala, Java и равенство

7 голосов
/ 06 августа 2010
val filesHere = (new java.io.File(".")).listFiles
val filesHere2 = (new java.io.File(".")).listFiles

scala> filesHere == filesHere2
res0: Boolean = false

Это довольно противоречиво.Я предпочел бы ожидать, что filesHere и filesHere2 равны.

Это, безусловно, связано с несоответствием семантики между Java и Scala, например, в отношении массивов или (файлов) равенства.Очевидно, я что-то здесь упускаю!

Ответы [ 4 ]

17 голосов
/ 06 августа 2010

Если бы я управлял миром, я бы отказался от метода eq в Scala на том основании, что имя чрезвычайно , можно путать с равными и ==. Вместо этого в английском есть слово, которое выражает идентичность, а не равенство: я бы просто назвал его - это .

Точно так же я бы заменил ne от Scala (это ужасное имя, так как это сокращение и непонятно) на isnt .

Мне кажется, они действительно могут быть добавлены в AnyRef, и старые методы устарели даже на этой поздней стадии.

8 голосов
/ 06 августа 2010

Сравнение не работает должным образом, потому что этот Java API возвращает массив.

Массивы Scala и Java-массивы одинаковы за кулисами, и хотя массив Scala выглядит как класс, это просто java.io.File [] (в этом примере).причина, по которой проверка на равенство не может быть отменена.Для этого Scala должна использовать семантику Java.

Рассмотрим пример:

val filesHere = (new java.io.File(".")).listFiles.toList
val filesHere2 = (new java.io.File(".")).listFiles.toList

Это будет работать, как и ожидалось.

8 голосов
/ 06 августа 2010

Метод equals() массивов Java использует равенство ссылок, а не что-то более сложное, а Scala == - это просто equals().

Java.
4 голосов
/ 06 августа 2010

Вы можете прочитать здесь:

http://ofps.oreilly.com/titles/9780596155957/AdvancedObjectOrientedProgramming.html#EqualityOfObjects

но похоже, что если вы сделали: filesHere.sameElements(filesHere2) что это должно быть правдой.

Javadoc для этого здесь: http://www.scala -lang.org / апи / 2.6.0 / Скала / IterableProxy.html # sameElements% 28Iterable% 5BB% 5D% 29

UPDATE: * ** 1015 1016 * Несколько фрагментов из первой ссылки, которые могут быть полезны:

В Java, C ++ и C # оператор == проверяет ссылки, а не равенство значений. В отличие от этого, оператор Ruby == проверяет равенство значений. Какой бы язык вы ни использовали, помните, что в Scala == проверяет равенство значений.

В отношении == не работает должным образом в списках:

Хотя это может показаться противоречивым, поощрение явного теста на равенство двух изменяемых структур данных является консервативным подходом со стороны разработчиков языка. В конечном счете, это должно спасти вас от неожиданных результатов в ваших условных выражениях.

ОБНОВЛЕНИЕ 2:

Основываясь на комментариях от Рафаэля, я посмотрел спецификацию, и она была датирована двумя днями назад для самого последнего обновления, и я вижу их в http://www.scala -lang.org / files / archive / nightly / pdfs /ScalaReference.pdf:

Method equals: (Any)Boolean is structural equality, where two instances
are equal if they both belong to the case class in question and they have equal
(with respect to equals) constructor arguments.

class AnyRef extends Any {
    def equals(that: Any): Boolean = this eq that
    final def eq(that: AnyRef): Boolean = . . . // reference equality

Итак, похоже, что определение не изменилось в Scala 2.10.2, так как спецификация кажется согласованной. Если поведение отличается, то если вы пишете модульный тест, его следует отправить как ошибку для Scala.

...