scala> val a = Array [Double] (10)
a: Array[Double] = Array(10.0)
scala> val a = new Array [Double] (10)
a: Array[Double] = Array(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
Почему эти два выражения имеют разную семантику?
scala> val a = Array [Double] (10)
a: Array[Double] = Array(10.0)
scala> val a = new Array [Double] (10)
a: Array[Double] = Array(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
Почему эти два выражения имеют разную семантику?
Это немного запутанно, но Scala имеет понятие классов, которые вы можете создавать экземпляры и объекты, которые являются в основном одноэлементными экземплярами класса. Он также имеет понятие сопутствующих классов, которое представляет собой пару класса и объект с тем же именем. Этот механизм позволяет "классу" по существу иметь статические методы, которые в противном случае невозможны в Scala.
Array
имеет как класс, так и объект-компаньон. Кроме того, Array
объект имеет метод apply
. apply
означает, что вы можете создать объект с помощью Array(arg)
. Но поскольку Array
является сопутствующим классом, он также имеет конструктор, который можно вызвать с помощью более обычного механизма new Array(arg)
.
Проблема заключается в том, что apply
в объекте Array
имеет другую семантику, чем конструкторы Array
. Метод apply
создает массив из указанных объектов, поэтому, например, Array(1,2,3)
возвращает массив, состоящий из объектов 1
, 2
и 3
. С другой стороны, конструкторы принимают аргументы, которые определяют размер размеров массива (так что вы можете создавать многомерные массивы), а затем инициализировать все слоты значением по умолчанию.
Итак, в основном:
val a = Array [Double] (10)
вызывает метод apply
объекта Array
, который создает новый массив, содержащий заданные объекты.val a = new Array [Double] (10)
вызывает конструктор Array
, который создает новый массив с 10 слотами, все инициализируются значением по умолчанию 0.0
. new Array[Double](10)
должен быть эквивалентен new double[10]
в Java.
Но Scala также предоставляет удобные методы для синглетонов, соответствующих его классам сбора, а Array
не является исключением.
Таким образом, если вы можете сказать List(1,2,3,4,5)
, кажется естественным, что вы также можете сказать Array(1,2,3,4,5)
. И вы можете.
Но он оставляет одно в слегка неудобном положении, имея довольно разные результаты, в зависимости от того, добавляется ли слово new
или нет. Учитывая конкурирующие интересы, я думаю, что это лучшее решение в целом, но оно немного привыкает.