我想要做的是将此代码转换为Scala:
Object[] method1(Object obj) {
if (obj instanceof int[]) {
int sourceArr[] = (int[]) obj;
Integer[] res = new Integer[sourceArr.length];
for (int i = 0; i < sourceArr.length; i++)
res[i] = sourceArr[i];
return res;
}
else if // and so on for double, int, boolean ...
else if (obj instanceof Object[]) {
return (Object[]) obj;
} else {
return new Object[] { obj };
}
}
这是我的尝试:
def method1(obj: Any): Array[Any] = obj match {
case x: Array[AnyRef] => x
case x: Array[Int] => x
// and so on for Double, Boolean, Char, Byte, Long....
case _ => new Array[Any]()
}
错误:
1) overloaded method constructor Array with alternatives:
[error] (dim1: Int,dim2: Int,dim3: Int,dim4: Int,dim5: Int,dim6: Int,dim7: Int,dim8: Int,dim9: Int)Array[Any] <and>
[error] (dim1: Int,dim2: Int,dim3: Int,dim4: Int,dim5: Int,dim6: Int,dim7: Int,dim8: Int)Array[Any] <and>
[error] (dim1: Int,dim2: Int,dim3: Int,dim4: Int,dim5: Int,dim6: Int,dim7: Int)Array[Any] <and>
[error] (dim1: Int,dim2: Int,dim3: Int,dim4: Int,dim5: Int,dim6: Int)Array[Any] <and>
[error] (dim1: Int,dim2: Int,dim3: Int,dim4: Int,dim5: Int)Array[Any] <and>
[error] (dim1: Int,dim2: Int,dim3: Int,dim4: Int)Array[Any] <and>
[error] (dim1: Int,dim2: Int,dim3: Int)Array[Any] <and>
[error] (dim1: Int,dim2: Int)Array[Any] <and>
[error] (_length: Int)Array[Any]
[error] cannot be applied to ()
[error] case _ => new Array[Any]()
2) type mismatch;
[error] found : Array[Short]
[error] required: Array[Any]
[error] Note: Short <: Any, but class Array is invariant in type T.
[error] You may wish to investigate a wildcard type such as `_ <: Any`. (SLS 3.2.10)
[error] case x: Array[Short] => x
3) type mismatch;
[error] found : Array[Long]
[error] required: Array[Any]
[error] Note: Long <: Any, but class Array is invariant in type T.
[error] You may wish to investigate a wildcard type such as `_ <: Any`. (SLS 3.2.10)
[error] case x: Array[Long] => x
// and so on for each type I have -- Double, Boolean, Char, Byte, Long....
我该如何解决这个问题?在Scala中有更合理的方法吗? 请注意,我无法更改Java代码。
答案 0 :(得分:3)
在Java代码中,你必须重新打包数组,所以你必须在Scala中也这样做(尽管map
很容易):
case x: Array[Int] => x.map(_.asInstanceOf[Any])
(哦,既然你正在返回Any
而不是AnyRef
,但两者对JVM来说都是一样的,只要寻找你想要返回的那个。所以不是:
case x: Array[AnyRef] => x.asInstanceOf[Array[Any]]
但:
case x: Array[Any] = x
)
你正在混淆构造函数调用Array
- 它接受一个长度的参数 - 使用apply
对象上的Array
方法,它可以让你指定内容。你可能意味着
case _ => Array[Any]()
或者如果你真的想像在Java代码中一样包装对象,
case x => Array(x)
答案 1 :(得分:2)
您可以删除最后一个案例:它是未确定的,因为其他案例已涵盖所有可能性(Any
只能是AnyVal
或AnyRef
)。
接下来,您应该更改返回类型,因为Array
是不变的,因此Int <: Any
(通过示例)并不意味着Array[Int] <: Array[Any]
def method1(obj: Any): Array[_] = obj match {
case x: Array[AnyRef] => x
case x: Array[Int] => x
// and so on for Double, Boolean, Char, Byte, Long....
}
这将编译。但是,这可能仍然不是你的意思。您的原始java版本执行原始数组的输入数组的副本,如果它是引用数组则返回该数组,如果它首先不是数组,则最终将输入包装到单个元素数组中。您的scala版本不会执行任何操作。 所以我认为你想要的只是这个:
def method1(obj: Any): Array[_] = obj match {
case x: Array[AnyRef] => x
case x: Array[_] => x.clone()
case x => Array( x )
}
答案 2 :(得分:1)
请尝试使用new Array[AnyRef]()
。 Object
是AnyRef
而不是Any
。
无论如何,如果.asInstanceOf[Array[Any]]
,您必须投射结果。 Java将数组视为协变,而Scala将它们视为不变量。