Как создать неоднородный массив в Scala?

В javascript мы можем:

["a string", 10, {x : 1}, function() {}].push("another value");

Что такое эквивалент Scala?

Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
28
0
29 359
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Массивы в Scala очень однородны. Это потому, что Scala - это язык со статической типизацией. Если вам действительно нужны псевдогетерогенные функции, вам необходимо использовать неизменяемую структуру данных, параметризованную ковариантно (большинство неизменяемых структур данных таковыми являются). List является каноническим примером, но Vector также является опцией. Тогда вы можете сделать что-то вроде этого:

Vector("a string", 10, Map("x" -> 1), ()=>()) + "another value"

Результатом будет тип Vector[Any]. Не очень полезно с точки зрения статической типизации, но все будет там, как было обещано.

Между прочим, «буквальный синтаксис» для массивы в Scala следующий:

Array(1, 2, 3, 4)     // => Array[Int] containing [1, 2, 3, 4]

Смотрите также: Дополнительная информация о постоянных векторах

Этот ответ ужасно сбивает с толку - дело в том, что пример OP отлично работает с Scala Array, как показывает ответ @ soc. Существуют и другие варианты, такие как List и Vector, но причины их использования или неиспользования не имеют ничего общего с тем, является ли вариант использования однородным или «псевдогетерогенным».

Greg Price 31.08.2011 09:37

Ответ пронизан жаргоном, который может сбить с толку. Это также многое объясняет, если вы понимаете, что он говорит. Я подозреваю, что эта фраза была сделана специально, поскольку OP исходит из javascript.

providence 01.10.2011 07:56

Нет, на самом деле так говорят аборигены Scala. Это совершенно нормально. (И я имею в виду это честно; я вовсе не пытаюсь быть саркастичным.)

James Moore 08.05.2012 03:55

Разве нельзя упаковать все эти вещи в Tuple, поскольку «кортеж объединяет фиксированное количество элементов вместе, так что их можно передавать как единое целое. В отличие от массива или списка, кортеж может содержать объекты с разными типы ". (взято из artima.com/pins1ed/collections.html)?

herom 22.10.2012 10:39

Скоро в Scala может появиться «разнородный» список: HList в Scala

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

James Moore 08.05.2012 03:56

Scala выберет наиболее конкретный тип элемента Array, который может содержать все значения, в этом случае ему нужен наиболее общий тип Any, который является супертипом любого другого типа:

Array("a string", 10, new { val x = 1 }, () => ()) :+ "another value"

Результирующий массив будет иметь тип Array[Any].

Лично я, вероятно, использовал бы кортежи, как упоминает Хером в комментарии.

scala> ("a string", 10, (1), () => {})
res1: (java.lang.String, Int, Int, () => Unit) = (a string,10,1,<function0>)

Но вы не можете легко присоединиться к таким структурам.

HList, упомянутый ePharaoh, «создан для этого», но я бы сам, вероятно, держался подальше от него. Он тяжелый для программирования типов и поэтому может нести с собой удивительную нагрузку (например, создание большого количества классов при компиляции). Просто будь осторожен. HList из вышеперечисленного (требуется библиотека MetaScala) будет (не доказано, поскольку я не использую MetaScala):

scala> "a string" :: 10 :: (1) :: () => {} :: HNil

Вы можете добавить и т. д. (Ну, по крайней мере, добавить) к такому списку, и он будет знать типы. Приставка создает новый тип, который имеет старый тип в качестве хвоста.

Тогда есть еще один не упомянутый подход. Классы (особенно классы case) очень легки в Scala, и вы можете сделать их однострочными:

scala> case class MyThing( str: String, int: Int, x: Int, f: () => Unit )
defined class MyThing

scala> MyThing( "a string", 10, 1, ()=>{} )
res2: MyThing = MyThing(a string,10,1,<function0>)

Конечно, это тоже не справится с добавлением.

Другие вопросы по теме