【问题标题】:How do I create a heterogeneous Array in Scala?如何在 Scala 中创建异构数组?
【发布时间】:2010-09-16 04:54:25
【问题描述】:

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

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

Scala 等价物是什么?

【问题讨论】:

    标签: arrays scala


    【解决方案1】:

    Scala 中的数组是非常同质的。这是因为 Scala 是一种静态类型语言。如果你真的需要伪异构特性,你需要使用参数化协变的不可变数据结构(大多数不可变数据结构都是)。 List 是那里的典型示例,但 Vector 也是一个选项。然后你可以这样做:

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

    结果将是Vector[Any] 类型。在静态类型方面不是很有用,但一切都会如期而至。

    顺便提一下,Scala 中 arrays 的“字面语法”如下:

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

    另见More info on persistent vectors

    【讨论】:

    • 这个答案非常令人困惑——事实上,正如@soc 的答案所示,OP 的示例与 Scala Array 完美配合。还有ListVector等其他选项,但使用或不使用的原因与用例是同质还是“伪异构”无关。
    • 答案带有行话,可能会让人困惑。如果你明白他在说什么,它也能解释很多。我怀疑这个措辞是故意的,因为 OP 来自 javascript。
    • 不,这确实是 Scala 本地人所说的。这是完全正常的。 (我的意思是说实话;我根本不想讽刺。)
    • 是不是也可以将所有这些东西打包成一个Tuple,因为“元组将固定数量的项目组合在一起,以便它们可以作为一个整体传递。不像数组或列表,元组可以包含不同类型的对象。” (取自artima.com/pins1ed/collections.html)?
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 虽然注意到 HList 根本不会改变语言,所以如果 HList 能做到,它总是在 Scala 中。
      【解决方案4】:

      就个人而言,我可能会使用元组,正如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
      

      您可以在这样的列表中附加等(好吧,至少是前置),它会知道类型。 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>)
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        • 1970-01-01
        • 1970-01-01
        • 2020-07-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多