6

この問題は、Java と Scala の統合に関連しています。わかりやすくするために、少し単純化しました。

私はJavaで書かれた2つのクラスを持っています:

class A<T>{}

class AT extends A<Boolean> {}

Java には、次の方法でクラスを使用するメソッドがあります。

public  A<Boolean> a(){
    return new AT();
}

同じことをscalaでもやりたいです。しかし、以下のコードはコンパイルされません。

def a(): A[Boolean] = {
    return new AT();
}

メッセージには次のように書かれています:

なぜそうなのか、どうすればそれができるのか、誰か説明できますか?

4

1 に答える 1

5

コードがコンパイルされない理由を理解するには、まず、Java はjava.lang.Booleanボックス化されたブール型を使用し、Scala は を使用することに注意してくださいscala.Boolean。ほとんどの場合、それらのいずれかを使用したいときに、メソッドがもう一方を返す (またはメソッド引数がもう一方を必要とする) 場合、暗黙的な変換が実行され、正しい型が使用されます。

あなたが Scala で書いたメソッドaは本当に を返しますA[java.lang.Boolean]A[java.lang.Boolean]と の間に暗黙的な変換がないため、この場合A[scala.Boolean]は自動的に戻りませんA[scala.Boolean]

これが事実であることを確認するために、このメソッドが問題なくコンパイルされることを確認できます。

def a: A[java.lang.Boolean] = new AT()

繰り返しになりますが、暗黙的な変換がないため、これも機能しません (以下で修正方法を確認できます)。

val instanceOfA: A[Boolean] = a
def a = new AT()
// Error: AT doesn't conform to A[Boolean] 

それを修正するには、キャストすることで必要な型に暗黙的に変換できます。

implicit def toScalaABoolean(a: A[java.lang.Boolean]): A[Boolean] =
        a.asInstanceOf[A[Boolean]]

aこれが完了すると、メソッドの戻り値の型を宣言する必要さえなくなります。

implicit def toDifferentBoolean(a: A[java.lang.Boolean]): A[Boolean] = 
     a.asInstanceOf[A[Boolean]]
val instanceOfA: A[Boolean] = a
def a = new AT()
于 2013-04-08T13:49:25.750 に答える