Попытка реализовать код, подобный найденному в примере высшего порядка функциональном из 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") }
^
Это верно, по крайней мере, с версией 2.7.6.final компилятора Scala в моей системе. Я могу достигнуть того, что я хочу в стиле Java способ явной реализации анонимного ActionListener.
button.addActionListener( new ActionListener() {
def actionPerformed(e:ActionEvent) { println("test") }
})
Насколько я понимаю, Scala должен смочь использовать ввод утки для рендеринга этой явной реализации ненужного ActionListener; итак, почему это не работающий здесь? Я не имею рядом ни с каким практическим опытом ввода утки в этой точке.
Утиная типизация не имеет никакого отношения к причине того, что ваш код не работает. Это происходит потому что система типов Scala не обеспечивает неявного преобразования между типом интерфейса и типом функции по умолчанию. Однако, если следующее неявное преобразование определено, ваш код будет работать правильно.
implicit def toActionListener(f: ActionEvent => Unit) = new ActionListener {
def actionPerformed(e: ActionEvent) { f(e) }
}
Это неявное преобразование обеспечивает преобразование из (ActionEvent => Unit) в ActionListner.
Scala не является утиной типизацией. Он имеет необязательную явную структурную типизацию, но это не имеет никакого отношения к тому, почему ваш код не работает.
Ваш код не работает, потому что JButton.addActionListener ожидает ActionListener
в качестве аргумента, а не функции. Даже если бы scala был утилизирован, вы не могли просто передать функцию, потому что те же методы, которые доступны в ActionListener
, недоступны для функции.
Обратите внимание, что в статье говорится: «Предположим на один прекрасный момент, что мы могли бы переписать Swing, чтобы в полной мере использовать синтаксис Scala», т.е. статья не претендует на то, чтобы показать вам реальный код, который работает.
Однако у scala есть собственный пакет Swing ( scala.swing
), который содержит классы, которые более «масштабны» в использовании, чем их эквиваленты в java.