4

Scala 2.8.1 /JavaFx2.0ベータ版で次のコードをコンパイルしようとした場合

new KeyValue(circle.translateYProperty, random() * height)

次のエラーが発生します。

[error]  found   : javafx.beans.property.DoubleProperty
[error]  required: javafx.beans.value.WritableValue[Any]
[error]             new KeyValue(circle.translateYProperty, random() * height)
[error]                                 ^
[error] one error found

この行は問題なくコンパイルされますが、次のようになります。

new KeyValue(circle.translateXProperty.asInstanceOf[WritableValue[Any]], random() * width)

KeyValueコンストラクターを確認したところ、次の署名があります。

public <T> KeyValue(javafx.beans.value.WritableValue<T> tWritableValue, T t) { /* compiled code */ }

circle.translateXPropertyは、次のインターフェイスを実装するDoublePropertyを返します。

public interface WritableNumberValue extends javafx.beans.value.WritableValue<java.lang.Number>

コンパイルするためにキャストするよりもエレガントなソリューションは何でしょうか?

4

2 に答える 2

5

-例外とBlaisorbladeのコメントに基づいて修正された回答-

ScalaとJavaの相互運用の問題ではなく、Scalaによる暗黙のアプリケーションの制限に直面しました。簡単な例を次に示します。

class Foo[T]
def f[T](x: Foo[T], y: T): T = y

f(new Foo[Number], new java.lang.Double(0)) // OK; infers T==Number
f[Number](new Foo[Number], 0)               // OK; uses implicit int2Integer(0)
// f(new Foo[Number], 0)                    // error
  • fとの一般的なスーパータイプがであるため、への最初の呼び出しは機能java.lang.Doublejava.lang.Numberます。java.lang.Numberこれは、の推定タイプですT

  • の2番目の呼び出しfは、コンパイラーに明示的に指示したために機能しT==java.lang.Numberます。コンパイラは、2番目の引数で0 : Intあるが期待される型と一致しないことを検出すると、からへjava.lang.Numberの暗黙的な変換を検索します。コンパイラはそれを見つけて適用します。すべては順調です。IntNumberPredef.int2Integer

  • 最初のパラメーターがを制約し、2番目の引数が言う(つまり、のスーパータイプである)ため、への3番目の呼び出しはf機能しません。との一般的なスーパータイプはですが、は共変ではないため、機能しません(つまり、をにキャストすることはできません)。これがコンパイラのエラーメッセージの要点です。コンパイラは、変換先の特定のタイプを認識していないため、暗黙的な変換を適用する方法を認識していないことに注意してください。T == NumberT >: IntTIntIntNumberAnyFoo[T]TFoo[Number]Foo[Any]T

投稿したJavaFXコードの奇妙な点の1つは、KeyValueクラスがジェネリックではなく、ジェネリックコンストラクターを持っていることです。興味深いことに、これはScalaでは不可能であるため、(私が知る限り)TScalaコードからパラメーターを明示的に制約する方法はありません。クラス全体KeyValueが一般的なものであれば、次のように書くこともできます。

new KeyValue[Number](circle.translateYProperty, random() * height)

double2Doubleこれは、コンパイラが変換を推測するため、Exceptionが投稿したコードと同等です。

于 2011-08-05T21:06:09.083 に答える
4

私は数日前に同じ問題を抱えていました。さまざまなことを試した後、私はそれで終わりました。

new KeyValue(circle.translateYProperty, double2Double(random() * height))

(説明についてはBlaisorbladeのコメントを参照してください)

于 2011-08-06T21:50:28.327 に答える