2

我想做的是将此代码转换为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 代码。

4

3 回答 3

3

在您的 Java 代码中,您必须重新打包数组,因此您也必须在 Scala 中执行相同的操作(尽管使用 很容易map):

  case x: Array[Int] => x.map(_.asInstanceOf[Any])

(哦,既然你返回Anynot AnyRef,但两者对 JVM 来说确实是一回事,只需寻找你想要返回的那个。所以不是:

  case x: Array[AnyRef] => x.asInstanceOf[Array[Any]]

但:

  case x: Array[Any] = x

)

而且您正在将构造函数调用与对象上的方法混合在一起Array——它接受一个参数,即长度——它可以让你指定内容。你可能是说applyArray

  case _ => Array[Any]()

或者如果你真的想像在 Java 代码中那样包装对象,

  case x => Array(x)
于 2013-06-24T15:32:24.480 回答
2

您可以只删除最后一种情况:它是不必要的,因为其他情况已经涵盖了所有可能性(anAny只能是 anAnyVal或 an 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 )
}
于 2013-06-24T15:35:39.677 回答
1

试试new Array[AnyRef]()吧。一个Object不是AnyRef一个Any

无论如何,如果.asInstanceOf[Array[Any]]. Java 将数组视为协变的,而 Scala 将它们视为不变的。

于 2013-06-24T15:33:28.543 回答