Scala с использованием библиотек Java, используя поддержку лямбда-выражений в Java 8
Согласно:
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#lambda-expressions-in-gui-applications
Ранее:
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
Теперь мы можем:
btn.setOnAction(
event -> System.out.println("Hello World!")
);
Теперь я пытаюсь сделать это в Scala при использовании библиотеки Java.
Я использую JavaFX (который включен по умолчанию в Java 1.8 SE).
Попробуйте:
chart.setOnMouseClicked( (e: MouseEvent) => println("Noice") )
Однако я получаю:
Error:(204, 46) type mismatch;
found : javafx.scene.input.MouseEvent => Unit
required: javafx.event.EventHandler[_ >: javafx.scene.input.MouseEvent]
chart.setOnMouseClicked( (e: MouseEvent) => println("Noice") )
^
Старый стиль отлично работает:
chart.setOnMouseClicked( new EventHandler[MouseEvent] {
override def handle(event: MouseEvent): Unit = println("NOT NOICE")
} )
Я установил уровень языка проекта на Java 8 в IntelliJ, я использую Scala 2.11.1 и Java от Oracle версии 1.8.0_05
Что мне здесь не хватает? или просто невозможно передать лямбда-выражение из Scala на Java так же, как это сделано в указанном примере?
Ответы
Ответ 1
Для версии scala версии 2.12 поддержка появляется из коробки.
Состояние для pre-2.12:
Lambdas был представлен в java языке и имеет мало общего с функциями scala. Они скомпилированы до другого байт-кода, имеет разную иерархию (функции scala были здесь задолго до этого, и, по-видимому, разработчики java выбрали реализацию чистой комнаты без совместимости с scala).
В настоящее время поддержка в значительной степени ограничена и то, что вы пытаетесь сделать, невозможно (из коробки):
Серия scala 2.11 нацелена на Java 6, с (развивающейся) экспериментальной поддержка Java 8. В версии 2.11 поддержка Java 8 в основном ограничена чтение байт-кода Java 8 и разбор источника Java 8. Мы будем расширение scala (экспериментальное) Java 8 поддержка и взаимодействие по всему серии 2.11. - См. Больше на: https://typesafe.com/blog/scala-211-has-arrived#sthash.ukr4FSpU.dpuf
текущие усилия для решения этой проблемы
См. также обсуждение scala дорожной карты для поддержки функций java 8.
Ответ 2
Одним из способов достижения этого является использование неявных преобразований, что вам нужно сделать, это создать новый Object, который обрабатывает все эти преобразования, примерно так:
import javafx.scene.input.MouseEvent
import javafx.event.EventHandler
object FXEvent2HandlerImplicits{
implicit def mouseEvent2EventHandler(event:(MouseEvent)=>Unit) = new EventHandler[MouseEvent]{
override def handle(dEvent:MouseEvent):Unit = event(dEvent)
}
}
Затем просто импортируйте его в любой файл, который может понадобиться для преобразования:
import FXEvent2HandlerImplicits._
//From now on within scope you can now call events like Java8 Lambdas
chart.setOnMouseClicked( (e: MouseEvent) => println("Noice") )
Это просто синтаксический сахар, чтобы архивировать то же самое более элегантным способом.