Подтвердить что ты не робот

Почему функция Array == не возвращает true для Array (1,2) == Array (1,2)?

В Программирование в 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

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

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

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

  • Как заставить функцию equals работать с массивами?

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

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