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 需要 anActionListener作为其参数,而不是函数。即使 scala 是鸭式的,你也不能只传递一个函数,因为在 anActionListener上可用的相同方法在函数上不可用。

请注意,文章说“让我们假设我们可以重写 Swing 以充分利用 Scala 的语法”,也就是说,文章并没有声称向您展示实际的工作代码。

然而 scala 确实有它自己的 swing 包 ( scala.swing),其中包含的类比它们的 java 等价物更“scalaish”。

于 2010-07-13T16:36:03.480 回答