如何在Scala中创建异构数组?

时间:2008-10-09 05:00:50

标签: arrays scala

在javascript中,我们可以这样做:

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

什么是Scala等价物?

4 个答案:

答案 0 :(得分:40)

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]

另见More info on persistent vectors

答案 1 :(得分:18)

Scala将选择可以包含所有值的最具体的Array元素类型,在这种情况下,它需要最通用的类​​型Any,它是所有其他类型的超类型:

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

结果数组的类型为Array[Any]

答案 2 :(得分:4)

Scala很快就会获得“异构”列表的能力: HList in Scala

答案 3 :(得分:2)

就个人而言,我可能会使用元组,正如herom在评论中提到的那样。

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

但你不能轻易地附加到这样的结构上。

ePharaoh提到的HList是“为此而制造的”,但我可能会自己保持清醒。它在类型编程上很重要,因此可能会带来令人惊讶的负载(即在编译时创建很多类)。小心点上面的HList(需要MetaScala库)将是(由于我不使用MetaScala而未经证实):

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

你可以在这样的列表中附加等等(好吧,至少是前置),它会知道类型。预先创建一个新类型,它将旧类型作为尾部。

然后还有一种方法尚未提及。类(特别是案例类)在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>)

当然,这也不会处理附加。