在Scala中创建具有任意类型和映射的三维数组

时间:2018-08-20 06:51:27

标签: java scala scala-collections type-theory

当我们在Scala中使用任意类型的数组X时,我们尝试使用map对每个值进行双重嵌套(即将[1,2,3]变成{{ 1}}),我们得到一个[[[1]],[[2]],[[3]]]。下面的代码是一个失败的最小示例:

java.lang.ArrayStoreException

此外,将import scala.reflect.ClassTag def doubleNest[X: ClassTag](values: Array[X]): Array[Array[Array[X]]] = { values map { value => Array(Array(value)) } } doubleNest(Array(1,2,3)) 变成[[1],[2],[3]]时似乎会出现错误。下面的代码是一个最小的失败示例(错误发生在第二个[[[1]],[[2]],[[3]]]中):

map

为什么会这样?

1 个答案:

答案 0 :(得分:2)

Scala似乎不喜欢直接制作嵌套的通用数组。甚至失败了:

def foo[T: ClassTag](t: T) = Array(Array(t))
foo(1) // java.lang.ClassCastException: java.base/[Ljava.lang.Object; cannot be cast to [[I

(在这种情况下,可能是因为ClassTag看着被擦除的类,所以Array.apply进行了同样的操作,并创建了Array[Array[Object]]而不是Array[Array[T]]。)

为此看来,ClassTag具有方法wrapnewArray。因此,您可以使用涉及implicitly[ClassTag[X]].wrap.wrap.newArray(array.length)的某些丑陋方法来完成工作,或者可以执行此操作,这似乎是通过从不直接要求它创建嵌套数组来实现的:

import scala.reflect.ClassTag

def nest[C: ClassTag](arr: Array[C]) = arr.map(Array(_))

def doubleNest[X: ClassTag](array: Array[X]): Array[Array[Array[X]]] =
  nest(nest(array))