【问题标题】:Type mismatch error with 2D Array in ScalaScala中二维数组的类型不匹配错误
【发布时间】:2014-06-04 01:44:37
【问题描述】:

我在 Scala 的函数参数中定义了 Seq[Seq[Byte]] 类型。

def checkAllZeroElementsInTable(table: Seq[Seq[Byte]]) : Boolean = {
...

当我给出Array[Array[Byte]] 类型的参数时,出现类型不匹配错误。

val table = Array(Array[Byte](0,0,0),Array[Byte](0,0,0),Array[Byte](0,0,0),Array[Byte](0,0,1))

这是错误信息:

最简单的解决方案是重新定义函数,但我认为这不是最好的解决方案。

def checkAllZeroElementsInTable(table: Array[Array[Byte]]) : Boolean = {
...

为什么会出现这个错误,以及如何解决这个问题?

【问题讨论】:

标签: scala scala-collections


【解决方案1】:

令人惊讶的是,Array 不是 Sequence,至少通过@Brian 指出的通常的继承方式。但此外——问题的出现是因为您使用 嵌套数组 并且因为 scala 中隐式转换的工作方式

首先,编译器会遍历您的所有代码并愉快地移动点点滴滴。现在,如果出现类型检查错误,它会查看它允许执行的隐式转换列表,以修复否则不可编译的代码(其中一个是Array => Seq)。因此编译器在左侧看到Seq[Seq[Byte]] 并尝试应用该转换。在这样的应用程序之后,它在右手边得到了什么?对,它得到了Seq[Array[Byte]],而不是Seq[Seq[Byte]]

因此,此修复尝试失败,最终编译器因该错误而退出:Type mismatch, blah blah blah。正如您可能已经猜到的那样,implicit conversions do not go into depth(实际上这是理智的规则)。但是,在这个例子中,scalac 会愉快地进行类型检查和编译这样的代码:

def foo(seq: Seq[Array[Int]]) = println(seq)
foo(Array(Array(1)))
// WrappedArray([I@afb9176)

遗憾的是,解决方案是最初使用 Seqs,因为我认为手动转换封闭数组对您来说不是一个可行的选择。

编辑:事实上,它也失败了,因为没有隐式转换,它的目的是转换集合的元素,但是如果你要引入一个,你会被上面解释的机制阻止(但是,它可以解决额外的麻烦)

【讨论】:

    【解决方案2】:

    错误是因为Array 不是Seq 类型。 Array 是 Scala 对 Java 数组的表示。

    Array 的类型层次结构表明它不是从 Seq 继承的,如您的错误消息所述。

    您可以更改您的函数以使用Array,如您所记。如果您需要可变集合,请查看scala.collection.mutable.ArrayBuffer。对于不可变集合,还有其他选项,最佳选择取决于您的算法如何访问集合。这有很好的收集特征信息:http://www.scala-lang.org/docu/files/collections-api/collections_40.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-05
      • 2012-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多