您可以使用数组被隐式转换为ArrayOps的事实,这使得它们可以作为标准集合使用。基本上,您需要做的就是选择一个适合两者通用的接口ArrayOps
,List
并将其声明为变量的显式类型以触发转换:
val s: collection.SeqLike[Int,_] =
if (condition) Array(1, 2, 3)
else List(1, 2, 3, 4);
print(s.size)
更新:对于多维数组,您还需要触发内部的隐式转换,因为Array[ArrayOps[X]]
不可分配给Array[Array[X]]
,反之亦然:
type SL[+A] = SeqLike[A,_]
val s1: SL[SL[Int]] =
if (x) Array(Array(1, 2, 3): SL[Int]) else List(List(1, 2, 3, 4));
print(s1.size)
列表不需要它,因为它们的类型参数是协变的,因此当使用它们的超级接口之一时,它们可以在任何地方使用。
如果您自己从一组固定的元素创建数组,您可以创建帮助函数来返回两个可能的包装器之一(ArrayOps
和WrappedArray
)。那么您将不需要任何显式输入:
import scala.collection.mutable._
import scala.reflect.ClassManifest
// Using ArrayOps
def arrayO[A: ClassManifest](xs: A*): ArrayOps[A] = Array(xs : _*);
val s2 =
if (x) arrayO(arrayO(1, 2), arrayO(3)) else List(List(1, 2), List(3, 4));
println(s2.size)
// UsingWrappedArray
def arrayW[A: ClassManifest](xs: A*): WrappedArray[A] = Array(xs : _*);
val s3 =
if (x) arrayW(arrayW(1, 2), arrayW(3)) else List(List(1, 2), List(3, 4));
println(s3.size)
如果您有想要包装的现有数组,则需要包装每个级别,如
val a4 = Array(Array(1, 2, 3), Array(5, 6));
val s4: SL[SL[Int]] = a.map(x => x: SL[Int])