Scala ActionListener / несоответствие типов анонимной функции

Попытка реализовать код, подобный найденному в примере высшего порядка функциональном из 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; итак, почему это не работающий здесь? Я не имею рядом ни с каким практическим опытом ввода утки в этой точке.

6
задан PeterT 13 July 2010 в 16:15
поделиться

2 ответа

Утиная типизация не имеет никакого отношения к причине того, что ваш код не работает. Это происходит потому что система типов Scala не обеспечивает неявного преобразования между типом интерфейса и типом функции по умолчанию. Однако, если следующее неявное преобразование определено, ваш код будет работать правильно.

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

Это неявное преобразование обеспечивает преобразование из (ActionEvent => Unit) в ActionListner.

11
ответ дан 8 December 2019 в 15:58
поделиться

Scala не является утиной типизацией. Он имеет необязательную явную структурную типизацию, но это не имеет никакого отношения к тому, почему ваш код не работает.

Ваш код не работает, потому что JButton.addActionListener ожидает ActionListener в качестве аргумента, а не функции. Даже если бы scala был утилизирован, вы не могли просто передать функцию, потому что те же методы, которые доступны в ActionListener , недоступны для функции.

Обратите внимание, что в статье говорится: «Предположим на один прекрасный момент, что мы могли бы переписать Swing, чтобы в полной мере использовать синтаксис Scala», т.е. статья не претендует на то, чтобы показать вам реальный код, который работает.

Однако у scala есть собственный пакет Swing ( scala.swing ), который содержит классы, которые более «масштабны» в использовании, чем их эквиваленты в java.

4
ответ дан 8 December 2019 в 15:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: