Scala ActionListener/匿名函数类型不匹配

发布于 2024-09-09 03:19:26 字数 929 浏览 0 评论 0原文

尝试实现与 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 来说是这样。在我的系统上是最终的。我能够以 Java 风格的方式显式实现匿名 ActionListener 来实现我想要的目标。

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

据我了解,Scala 应该能够使用鸭子类型来使 ActionListener 的显式实现变得不必要;那么为什么它在这里不起作用呢?目前我几乎没有鸭子打字的实际​​经验。

Attempting to implement code similar to that found in the higher-order-function example from 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)

leads to the following

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

This is true at least with Scala compiler version 2.7.6.final on my system. I am able to achieve what I want in the Java-style way of explicitly implementing an anonymous ActionListener.

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

As far as I understand, Scala should be able to use duck-typing to render this explicit implementation of ActionListener unnecessary; so why isn't it working here? I have next to no practical experience of duck-typing at this point.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

唐婉 2024-09-16 03:19:26

鸭子打字与您的代码不起作用的原因无关。这是
因为Scala的类型系统不提供接口类型之间的隐式转换
和默认的函数类型。但是,如果定义了以下隐式转换,
你的代码工作正常。

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

此隐式转换提供从 (ActionEvent => Unit) 到 ActionListner 的转换。

Duck-typing has nothing to do with the reason that your code doesn't work. It is
because Scala's type system doesn't provide implicit conversion between interface type
and function type by default. However, if the following implicit conversion is defined,
your code works correctly.

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

This implicit conversion provides conversions from (ActionEvent => Unit) to ActionListner.

停滞 2024-09-16 03:19:26

Scala 不是鸭子类型的。它具有可选的、显式的结构类型,但这与代码不起作用的原因没有任何关系。

您的代码不起作用,因为 JButton.addActionListener 需要 ActionListener 作为其参数,而不是函数。即使 scala 是鸭子类型的,您也不能只传递函数,因为在 ActionListener 上可用的相同方法在函数上不可用。

请注意,该文章说“让我们假设一个幸福的时刻,我们可以重写 Swing 以充分利用 Scala 的语法”,即该文章并未声称向您展示实际有效的代码。

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

Scala isn't duck-typed. It has optional, explicit structural-typing, but that doesn't have anything to do with why your code does not work.

Your code does not work, because JButton.addActionListener expects an ActionListener as its argument, not a function. Even if scala were ducktyped, you couldn't just pass a function because the same methods available on an ActionListener are not available on a function.

Note that the article says "Let’s assume for one blissful moment that we could rewrite Swing to take full advantage of Scala’s syntax", i.e. the article does not claim to show you actual code that works.

However scala does have it's own swing package (scala.swing) which contains classes which are more "scalaish" to use than their java equivalents.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文