Java 在Scala中创建任意类型和贴图的三维数组

Java 在Scala中创建任意类型和贴图的三维数组,java,scala,scala-collections,type-theory,Java,Scala,Scala Collections,Type Theory,当我们在Scala中有一个任意类型的数组X,并尝试使用map对其每个值进行双嵌套时(即,将[1,2,3]转换为[[1]]、[[2]]、[[3]]]),我们得到一个java.lang.ArrayStoreException。下面的代码是一个最小的失败示例: import scala.reflect.ClassTag def doubleNest[X: ClassTag](values: Array[X]): Array[Array[Array[X]]] = { values map { va

当我们在Scala中有一个任意类型的数组
X
,并尝试使用
map
对其每个值进行双嵌套时(即,将
[1,2,3]
转换为
[[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]]
时似乎会出现错误。下面的代码是一个最小的失败示例(错误发生在第二个映射中):


为什么会发生这种情况?

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
也有用于此目的的方法和。因此,您可以使用一些涉及隐式[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))
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))