How do I create a heterogeneous Array in Scala?

不羁岁月 提交于 2019-12-18 12:49:12

问题


In javascript, we can do:

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

What is the Scala equivalent?


回答1:


Arrays in Scala are very much homogeneous. This is because Scala is a statically typed language. If you really need pseudo-heterogeneous features, you need to use an immutable data structure that is parametrized covariantly (most immutable data structures are). List is the canonical example there, but Vector is also an option. Then you can do something like this:

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

The result will be of type Vector[Any]. Not very useful in terms of static typing, but everything will be in there as promised.

Incidentally, the "literal syntax" for arrays in Scala is as follows:

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

See also: More info on persistent vectors




回答2:


Scala will choose the most specific Array element type which can hold all values, in this case it needs the most general type Any which is a supertype of every other type:

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

The resulting array will be of type Array[Any].




回答3:


Scala might get the ability for a "heterogeneous" list soon: HList in Scala




回答4:


Personally, I would probably use tuples, as herom mentions in a comment.

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

But you cannot append to such structures easily.

The HList mentioned by ePharaoh is "made for this" but I would probably stay clear of it myself. It's heavy on type programming and therefore may carry surprising loads with it (i.e. creating a lot of classes when compiled). Just be careful. A HList of the above (needs MetaScala library) would be (not proven since I don't use MetaScala):

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

You can append etc. (well, at least prepend) to such a list, and it will know the types. Prepending creates a new type that has the old type as the tail.

Then there's one approach not mentioned yet. Classes (especially case classes) are very light on Scala and you can make them as one-liners:

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>)

Of course, this will not handle appending either.



来源:https://stackoverflow.com/questions/185972/how-do-i-create-a-heterogeneous-array-in-scala

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!