如何在 Scala 中创建异构数组?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/185972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I create a heterogeneous Array in Scala?
提问by Leo
In javascript, we can do:
在javascript中,我们可以这样做:
["a string", 10, {x : 1}, function() {}].push("another value");
What is the Scala equivalent?
什么是 Scala 等价物?
回答by Daniel Spiewak
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). Listis the canonical example there, but Vectoris also an option. Then you can do something like this:
Scala 中的数组非常相似。这是因为 Scala 是一种静态类型语言。如果确实需要伪异构特征,则需要使用参数化协变的不可变数据结构(大多数不可变数据结构都是)。 List是那里的规范示例,但Vector也是一种选择。然后你可以做这样的事情:
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.
结果将是类型Vector[Any]。在静态类型方面不是很有用,但一切都会如承诺的那样。
Incidentally, the "literal syntax" for arraysin Scala is as follows:
顺便提一下,Scala 中数组的“文字语法”如下:
Array(1, 2, 3, 4) // => Array[Int] containing [1, 2, 3, 4]
See also: More info on persistent vectors
另请参阅:有关持久向量的更多信息
回答by soc
Scala will choose the most specific Array element type which can hold all values, in this case it needs the most general type Anywhich is a supertype of every other type:
Scala 将选择可以容纳所有值的最具体的 Array 元素类型,在这种情况下,它需要最通用的类型Any,它是所有其他类型的超类型:
Array("a string", 10, new { val x = 1 }, () => ()) :+ "another value"
The resulting array will be of type Array[Any].
结果数组的类型为Array[Any]。
回答by ePharaoh
Scala might get the ability for a "heterogeneous" list soon: HList in Scala
Scala 可能很快就会获得“异构”列表的能力: Scala 中的 HList
回答by akauppi
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):
ePharaoh 提到的 HList 是“为此而制作的”,但我自己可能会远离它。它在类型编程上很重,因此可能会带来惊人的负载(即在编译时创建很多类)。小心点。上述(需要 MetaScala 库)的 HList 将是(未证明,因为我不使用 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.
您可以将等(好吧,至少是前置)附加到这样的列表中,它会知道类型。Prepending 创建一个新类型,以旧类型作为尾部。
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 上非常简单,您可以将它们作为单行代码:
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.
当然,这也不会处理附加。

