6

http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-6の高階関数の例にあるものと同様のコードを実装しようとしています。

val button = new JButton("test")
button.addActionListener{ e:ActionEvent => println("test") }
add(button)

以下につながる

error: type mismatch;
found   : (java.awt.event.ActionEvent) => Unit 
required: java.awt.event.ActionListener
   button.addActionListener{ e:ActionEvent => println("test") }
                                           ^

これは、少なくとも私のシステムの Scala コンパイラ バージョン 2.7.6.final には当てはまります。匿名のActionListenerを明示的に実装するJavaスタイルの方法で、私が望むものを達成することができます。

button.addActionListener( new ActionListener() {
  def actionPerformed(e:ActionEvent) { println("test") }
})

私の知る限り、Scala はダックタイピングを使用して、この ActionListener の明示的な実装を不要にすることができるはずです。では、なぜここで機能しないのですか?この時点で、ダックタイピングの実際の経験はほとんどありません。

4

2 に答える 2

11

ダックタイピングは、コードが機能しない理由とは何の関係もありません。これは、Scalaの型システムがデフォルトでインターフェース型と関数型の間の暗黙的な変換を提供しないためです。ただし、次の暗黙的な変換が定義されている場合、コードは正しく機能します。

implicit def toActionListener(f: ActionEvent => Unit) = new ActionListener {
  def actionPerformed(e: ActionEvent) { f(e) }
}

この暗黙の変換は、(ActionEvent => Unit)からActionListnerへの変換を提供します。

于 2010-07-13T16:50:39.320 に答える
4

Scala はダック型ではありません。オプションの明示的な構造型付けがありますが、それはコードが機能しない理由とは関係ありません。

JButton.addActionListener はActionListener引数として関数ではなく を想定しているため、コードは機能しません。scala がダックタイプ化されていたとしても、関数で使用できる同じメソッドを関数で使用できないため、単に関数を渡すことはできませんでしたActionListener

この記事には、「Scala の構文を最大限に活用するために Swing を書き直すことができると仮定してみましょう」と書かれていることに注意してください。

ただし、scala には独自の swing パッケージ ( scala.swing) があり、Java の同等品よりも「scalaish」なクラスを使用できます。

于 2010-07-13T16:36:03.480 に答える