简体   繁体   中英

Scala ActionListener / anonymous function type mismatch

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.

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.

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", ie 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM