【问题标题】:Scala using Java libraries, taking advantage of lambda expressions support in Java 8Scala 使用 Java 库,利用 Java 8 中的 lambda 表达式支持
【发布时间】:2014-06-23 15:14:40
【问题描述】:

根据: 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!")
);

现在,我尝试在使用 Java 库时在 Scala 中执行此操作。

我正在使用 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")
} )

我在 IntelliJ 中将项目语言级别设置为 Java 8,我使用的是 Scala 2.11.1,以及来自 Oracle 版本 1.8.0_05 的 Java

我在这里缺少什么?还是根本不可能像在提到的示例中那样将 lambda 表达式从 Scala 传递到 Java?

【问题讨论】:

    标签: scala lambda javafx java-8 javafx-8


    【解决方案1】:

    对于 scala 版本 2.12 及更高版本的支持开箱即用。

    2.12 之前的状态:

    Lambdas 是在 java 语言 中引入的,与 scala 函数有一点共同点。它们被编译为different bytecode,具有不同的层次结构(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

    ongoing efforts可以解决这个问题

    另见discussion on scala roadmap to support java 8 functions

    【讨论】:

    • 谢谢,我不知道Java 8只有实验性支持
    • 顺便说一句,你已经连续 3 天回答我的问题了……我才注意到又是你!
    • @Spacemonkey "2011 年左右跟踪 scala 用户" ;-)
    • 我只是在这里和linkedin上查看你的个人资料。我跟踪你!
    • Scala 2.12 将默认以 Java 8 为目标,但目前的路线图显示它要到 2016 年 1 月才会发布。
    【解决方案2】:

    实现此目的的一种方法是使用隐式转换,您需要创建一个新对象来处理所有这些转换,如下所示:

    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") )
    

    这只是语法糖,以更优雅的方式归档相同的内容

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-30
      • 2015-04-17
      相关资源
      最近更新 更多