Почему `Array (0,1,2) == Array (0,1,2)` не возвращает ожидаемый результат?

Насколько я понимаю, == в Scala определяет естественное равенство двух объектов.

Я ожидал, что Array(0,1,2) == Array(0,1,2) сравнит естественное равенство. Например, проверяет, все ли элементы массива возвращают истину при сравнении с соответствующими элементами другого массива.

Люди сказали мне, что Array в Scala - это просто Java [], которая только сравнивает идентичность. Разве не было бы более значимым вместо этого переопределить метод Array'sequals для сравнения естественного равенства?


person soc    schedule 19.03.2010    source источник
comment
Я не знаком со Scala. Однако уверены ли вы, что == не сравнивает, являются ли массивы псевдонимами (ссылками на один и тот же объект в памяти)? Я предполагаю, что это возможно, поскольку вы упомянули, что это связано с массивом Java.   -  person Cam    schedule 20.03.2010
comment
Это неудачная ситуация, как описывают другие ответы, но когда вы знаете, что имеете дело с Array, вы можете использовать sameElements и получить нужный ответ, избегая при этом всех упаковок, боксов и разъяснений.   -  person Randall Schulz    schedule 06.06.2010


Ответы (3)


Scala 2.7 попытался добавить функциональность к массивам Java [], но столкнулся с серьезными проблемами. Scala 2.8 объявила, что Array[T] есть T[], но предоставляет оболочки и эквиваленты.

Попробуйте следующее в 2.8 (отредактируйте / примечание: в RC3 GenericArray равно _5 _ - спасибо retronym за указание на это):

import scala.collection.mutable.{GenericArray=>GArray, WrappedArray=>WArray}
scala> GArray(0,1,2) == GArray(0,1,2)
res0: Boolean = true

scala> (Array(0,1,2):WArray[Int]) == (Array(0,1,2):WArray[Int])
res1: Boolean = true

GenericArray действует так же, как Array, за исключением того, что в него добавлены все полезности коллекций Scala. WrappedArray обертывает массив Java []; выше, я привел к нему простой массив (проще, чем вызов функции неявного преобразования), а затем сравнил обернутые массивы. Эти оболочки, хотя и поддерживаются массивом [], также предоставляют вам все полезные свойства коллекции.

person Rex Kerr    schedule 20.03.2010
comment
Есть ли какие-либо преимущества производительности / памяти / ввода / ... использования этих классов вместо e. г. Список тогда? Я мог представить, что GenericArray / WrappedArray добавит немало накладных расходов ... - person soc; 20.03.2010
comment
Нет, на самом деле они добавляют очень мало накладных расходов --_ 1_ - это один дополнительный класс, обернутый вокруг простого массива Java. List требуется дополнительный класс вокруг каждого отдельного элемента. Вы используете списки из-за простоты использования, классного сопоставления с образцом и неизменяемости, а не для эффективности. GenericArray имеет немного странное положение, как массив фиксированного размера: размер неизменен, но содержимое изменяемо. Кто-то может задаться вопросом, почему не использовать просто ArrayBuffer? - person Rex Kerr; 20.03.2010
comment
Вы можете очень хорошо использовать неизменяемый список из-за производительности. Неизменяемые коллекции могут избавить вас от необходимости делать защитные копии. В зависимости от приложения это может перевесить их накладные расходы. - person ziggystar; 22.03.2010
comment
@ziggystar: Иногда это правда, я согласен, хотя я еще не встречал ни одного случая в моем собственном коде - всегда было быстрее сделать что-то еще, но часто так гораздо больше работа, которую я бы не стал беспокоить. Неизменяемые списки часто очень хорошо работают в соотношении (время кодирования) / (время выполнения). - person Rex Kerr; 22.03.2010
comment
GenericArray теперь называется ArraySeq - person retronym; 06.06.2010
comment
@RexKerr Зачем использовать соотношение (время кодирования) / (время выполнения)? Разве мы не хотим стремиться к низкому времени кодирования И низкому времени выполнения? Возможно, codingTime * execTime с меньшим значением лучше или constant / (codingTime * execTime), где выше было бы лучше. - person J.D. Sandifer; 03.02.2019
comment
@ J.D.Sandifer - Вы, конечно, правы. Я имел в виду скорость выполнения, а не время выполнения. (Я хотел, чтобы это было соотношение, потому что в этой форме более ясен компромисс.) - person Rex Kerr; 15.02.2019

Scala не отменяет равенство Array, потому что это невозможно. При создании подкласса можно только переопределить методы. Поскольку Array не является подклассом (что невозможно), Scala не может переопределить его методы.

person Daniel C. Sobral    schedule 20.03.2010

Но Scala String - это также просто Java String, но Scala переопределяет равенство для сравнения естественного равенства.

Scala здесь ничего не отменяет; java.lang.String имеет зависящую от значения реализацию equals() (как и многие другие классы Java, но в отличие от массивов).

person Michael Borgwardt    schedule 19.03.2010
comment
Привет, Майкл, спасибо! Я исправил свой вопрос соответственно. В основном мне просто интересно, почему equals не переопределяется для возврата естественного равенства, такого как классы Collection (я знаю, что Array не принадлежит классам Collection!). - person soc; 20.03.2010
comment
Scala интерпретирует == как equals. Это все. String имеет equals, который делает что-то полезное, отличное от эталонного идентификатора. [] нет. - person Rex Kerr; 20.03.2010