Как мне создать гетерогенный массив в Scala? - PullRequest
28 голосов
/ 09 октября 2008

В javascript мы можем сделать:

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

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

Ответы [ 4 ]

40 голосов
/ 09 октября 2008

Массивы в 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]

См. Также : Подробнее о постоянных векторах

18 голосов
/ 23 мая 2011

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

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

Полученный массив будет иметь тип Array[Any].

4 голосов
/ 15 октября 2008

Скоро Scala может получить возможность «разнородного» списка: HList в Scala

2 голосов
/ 20 ноября 2012

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

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

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

Тогда есть еще один подход, который еще не упомянут. Классы (особенно тематические) очень легки в 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>)

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

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