在Scala中使用2D数组键入不匹配错误

时间:2014-06-03 16:19:17

标签: scala scala-collections

我在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))

这是错误消息:

enter image description here

最简单的解决方案是重新定义该功能,但我认为这不是最佳解决方案。

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

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

2 个答案:

答案 0 :(得分:4)

令人惊讶的是,Array不是 Seq ,至少通过@Brian指出的通常的继承方式。但另外 - 出现问题的原因是你使用嵌套数组,因为 scala中隐式转换的工作方式

首先,编译器遍历所有代码并愉快地移动位和螺栓。现在,如果存在类型检查错误,它会查看它允许执行的隐式转换列表,以便修复否则不可编译的代码(其中一个代码为Array => Seq)。因此,编译器会在左侧看到Seq[Seq[Byte]]并尝试应用该转换。申请后,右手边有什么?是的,它是Seq[Array[Byte]]而不是Seq[Seq[Byte]]

enter image description here

因此,此修复尝试失败,并且最终编译器因错误而失败: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,因为我不认为封闭阵列的手动转换对您来说是一个可行的选择。

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

答案 1 :(得分:1)

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

Array的类型层次结构显示,它不会从Seq继承,因为您的错误消息显示。 Array type hierarchy

您可以在注意时将功能更改为Array。如果您需要可变集合,请查看scala.collection.mutable.ArrayBuffer。对于不可变集合,还有其他选项,最佳选择取决于算法如何访问集合。这有关收集特征的良好信息:http://www.scala-lang.org/docu/files/collections-api/collections_40.html