Почему функция Array == не возвращает true для Array(1,2) == Array(1,2)?
В Программировании в Scala авторы пишут, что Scala's ==
Функция сравнивает равенство значений вместо ссылочного равенства.
Это работает, как и ожидалось в списках:
scala> List(1,2) == List(1,2)
res0: Boolean = true
Однако это не работает на массивах:
scala> Array(1,2) == Array(1,2)
res1: Boolean = false
Авторы рекомендуют использовать функцию sameElements вместо:
scala> Array(1,2).sameElements(Array(1,2))
res2: Boolean = true
В качестве объяснения они пишут:
Хотя это может показаться противоречивым, поощрение явного теста на равенство двух изменчивых структур данных является консервативным подходом со стороны разработчиков языка. В конечном счете, это должно спасти вас от неожиданных результатов в ваших условных выражениях.
Что это значит? О каких неожиданных результатах они говорят? Что еще можно ожидать от сравнения массивов, кроме как возвращать true, если массивы содержат одинаковые элементы в одной и той же позиции? Почему функция равенства работает на
List
но не наArray
?Как я могу заставить функцию equals работать на массивах?
3 ответа
Это правда, что объяснение, предложенное в книге, сомнительно, но, если честно, было более правдоподобно, когда они его написали. Это все еще верно в 2.8, но мы должны модернизировать различные рассуждения, потому что, как вы заметили, все другие коллекции выполняют сравнения элементов, даже если они изменчивы.
Пролилось много крови, пытаясь сделать массивы похожими на остальные коллекции, но это была чрезвычайно протекающая абстракция, и в конце концов это было невозможно. Было определено, правильно я думаю, что мы должны перейти к другой крайности и поставлять нативные массивы такими, какие они есть, используя неявные механизмы для расширения их возможностей. То, где это наиболее заметно падает, это toString и равно, потому что ни один из них не ведет себя разумно в массивах, но мы не можем перехватить эти вызовы с неявными преобразованиями, потому что они определены в java.lang.Object. (Преобразования происходят только тогда, когда выражение не проверяет тип, а те всегда проверяют тип.)
Таким образом, вы можете выбрать свое объяснение, но, в конце концов, массивы принципиально по-разному воспринимаются базовой архитектурой, и нет способа описать это, не заплатив где-то цену. Это не ужасная ситуация, но это то, что вы должны знать.
Этот точный вопрос был озвучен много раз (я тоже, см. Странное поведение типа Array).
Обратите внимание, что это только Array
коллекция, которая не поддерживает ==
, все остальные коллекции делают. Коренная причина в том, что Array
Ява array
,
Все дело в ссылочной прозрачности. Идея в том, если два значения ==
, не должно иметь значения, какой вы используете для чего-то. Если у вас есть два массива с одинаковым содержимым, то ясно, какой из них вы модифицируете, поэтому ==
возвращает false, если они не совпадают.