Почему функция Array == не возвращает true для Array (1,2) == Array (1,2)? - PullRequest
22 голосов
/ 17 сентября 2010

In Программирование в Scala авторы пишут, что функция == в Scala сравнивает равенство значений вместо ссылочного равенства.

Это работает, как ожидается, в списках:

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

В качестве пояснения они пишут:

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

  1. Что это значит?О каких неожиданных результатах они говорят?Что еще можно ожидать от сравнения массивов, кроме как возвращать true, если массивы содержат одинаковые элементы в одной и той же позиции?Почему функция равенства работает с List, а не с Array?

  2. Как заставить функцию равенства работать с массивами?

Ответы [ 3 ]

27 голосов
/ 18 сентября 2010

Это правда, что объяснение, предложенное в книге, сомнительно, но, если честно, было более правдоподобно, когда они его написали. Это все еще верно в 2.8, но мы должны модернизировать различные рассуждения, потому что, как вы заметили, все другие коллекции выполняют сравнения элементов, даже если они изменчивы.

Пролито много крови, пытаясь сделать массивы похожими на остальные коллекции, но это была чрезвычайно протекающая абстракция, и в конце концов это было невозможно. Было определено, правильно я думаю, что мы должны перейти к другой крайности и предоставить родные массивы такими, какие они есть, используя неявные механизмы для расширения их возможностей. То, где это наиболее заметно падает, это toString и равно, потому что ни один из них не ведет себя разумно в массивах, но мы не можем перехватить эти вызовы с неявными преобразованиями, потому что они определены в java.lang.Object. (Преобразования происходят только тогда, когда выражение не проверяет тип, а те всегда проверяют тип.)

Таким образом, вы можете выбрать свое объяснение, но, в конце концов, массивы принципиально по-разному относятся к базовой архитектуре, и нет способа описать это, не заплатив где-нибудь цену. Это не ужасная ситуация, но это то, что вы должны знать.

7 голосов
/ 17 сентября 2010

Этот точный вопрос был озвучен много раз (я тоже, см. Странное поведение типа Array ).

Обратите внимание, что ТОЛЬКО коллекция Array не поддерживает ==, как все остальные коллекции.Основная причина в том, что Array - это Java array.

0 голосов
/ 17 сентября 2010

Все дело в ссылочной прозрачности.Идея в том, что если два значения ==, не должно иметь значения, какое из них вы используете для чего-либо.Если у вас есть два массива с одинаковым содержимым, то ясно, какой из них вы изменяете, поэтому == возвращает false, если они не являются одинаковыми единица.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...