【问题标题】:Pattern matching on nested arrays in ScalaScala中嵌套数组的模式匹配
【发布时间】:2017-12-16 16:08:52
【问题描述】:

我想创建Any 类型的数组,如下所示:

val arr: Array[Any] = Array(Array(1, 2, Array(3)), 4)

然后我想用这个代码使用尾递归使它变平:

def flatten(xs: Array[Any]): Array[Any] = {

    @tailrec
    def makeFlat(xs: List[Any], res: List[Any]): List[Any] = xs match {
      case Nil => res
      case head :: tail => head match {
        case h: Array[Any] => makeFlat(h.toList ::: tail, res)
        case _ => makeFlat(tail, res :+ head)
      }
    }

    makeFlat(xs.toList, Nil).toArray
}  

我使用的是 Scala 2.12 版本。

当迭代来自源数组的内部数组Array(3) 时,模式匹配case h: Array[Any] 不起作用。这很奇怪,因为Int 扩展了Any。我尝试调试并意识到这个数组是int[1](原始整数数组)。

为什么 scala 决定将其作为原始数组以及我如何解决这种情况?

【问题讨论】:

  • Scala 将 Array(3) 的类型推断为 Array[Int],因为您只在其中存储了一个 Int。您的 Array[Any] 类型仅指顶级数组。 val arr: Array[Any] = Array(Array(1, 2, Array[Any](3)), 4) 将为 Array(3) 创建一个 Array[Any]。

标签: scala types pattern-matching


【解决方案1】:

它不起作用,因为你没有让它推断类型。

将case h: Array[Any] 替换为case h: Array[_] 即可。

【讨论】:

    【解决方案2】:

    Array 是 java 类,不是 scala 类

    它不支持方差

    见http://docs.scala-lang.org/tutorials/tour/variances.html

    【讨论】:

    • 真的吗?但我在 scala 文档中读到了 Array 类。请查看此链接scala-lang.org/api/2.12.1/scala/Array.html。
    • 它的运行时类是java类,所有附加的成员函数都是在编译时翻译的。最重要的是,它被定义为Array[T] 而不是Array[+T]
    猜你喜欢
    • 2013-09-13
    • 2011-08-11
    • 2019-06-15
    • 2018-07-10
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    相关资源
    最近更新 更多