2

次の Java コードを Scala コードに変換したい:

Object method1(Object ... objArray) {
  if (objArray instanceof MyClass1[]) {
      Object resArray[] = new Object[objArray.length];
      for (int i = 0; i < objArray.length; i++) {
        resArray[i] = objArray[i].toString();
      }
      return resArray;
    } else {
      List<Object> resArray = new ArrayList<Object>();
      for (int i = 0; i < objArray.length; i++) {
        for (Object obj: scalar(objArray[i])) {
          resArray.add(obj);
        }
      }
      return resArray.toArray();
    }
  }

  //..........
  private static class MyClass1 {       
  private Object obj;

  public MyClass1(Object obj) {
    this.obj = obj;
  }

  @Override
  public String toString() {
    return obj.toString();
  }
 }

これが私が持っているもので、エラーが発生します:

def method1(objs: Any*): Array[_] = objs match {
    case x: Array[MyClass1] => x.map(toString)  // MyClass1 looks like 
    case x => x.map(method2).toArray
  }

//...................
def method2(obj: Any): Array[_] = {....} //it's perfectly fine

class MyClass1 (obj: AnyRef) {
    override def toString = obj.toString
}

エラー:

1)pattern type is incompatible with expected type;
[error]  found   : Array[MyClass1]
[error]  required: Any*
[error]     case x: Array[MyClass1] => x.map(toString)

2)type mismatch;
[error]  found   : Array[MyClass1]
[error]  required: Any*
[error]     case x: Array[MyClass1] => x.map(toString)

3)could not find implicit value for evidence parameter of type ClassManifest[Array[_]]
[error]     case x => x.map(method2).toArray

これを解決するにはどうすればよいですか?

4

1 に答える 1

0

可変長引数

scala の可変引数はSeqではなくArrayです。のインスタンスobjsになることはできませんArray[MyClass1]

Array実際には、次のように取得できます。

def test(s: Any*) = s match {
  case wa: WrappedArray[_] => wa.array
  case _ => ???
}

しかし、あなたはArray[_]ではなくを得るでしょうArray[MyClass1]:

scala> test("a", "b", "c").isInstanceOf[Array[String]]
res0: Boolean = false

のすべての要素をチェックしてからArrayに変換できますが、それはあなたが望むものではないと思います:Array[_]Array[MyClass1]

scala> test("a", "b", "c") match {
     |   case a if a.forall{_.isInstanceOf[String]} => a.map{ case s: String => s }
     | }
res1: Array[String] = Array(a, b, c)

この場合、次は必要ありませんArray

def method1(objs: Any*): Array[_] = objs match {
  case x if x.forall{_.isInstanceOf[MyClass1]} => x.map{_.toString}.toArray
  ...
}

マニフェスト

ここで使用する必要がManifestあります:

def test[T: Manifest](es: T*) = {
  if (implicitly[Manifest[T]] <:< implicitly[Manifest[MyClass1]])
    es.map{_.toString}.toArray
  else 
    x.flatMap(method2).toArray
}

Manifestは型消去の回避策ですが、 からそのようなメソッドを呼び出すことはできませんJava

フラットマップ

Array[_]ではありませんObject[]。に置き換える必要がArray[_]ありArray[Any]ます。

あなたx.map(method2).toArrayが得るでしょうArray[Array[Any]]Array[Any](Javaコードのように)取得したいので、すべての配列を集約するflatMap代わりに使用する必要があります。map

toStringメソッドに関数を渡そうとしていますmap:

x.map(toString)

そのような機能はありません。作成する必要があります:

x.map{e => e.toString}

または短い:

x.map{_.toString}
于 2013-06-25T11:00:12.753 に答える