scala - Scala 中等效的 Java 双冒号 (::) 运算符

标签 scala vaadin vaadin-flow

我看过一些如何在 Scala 中编写::equvalant 的示例,例如将 System.out::println 传递给函数,但我无法弄清楚如何在 Scala 中编写此 Vaadin Grid 组件:

Grid<Person> grid = new Grid<>(Person.class, false);
grid.addColumn(Person::getFirstName).setHeader("First name");
grid.addColumn(Person::getLastName).setHeader("Last name");

这里的 get 方法是常规的 getter,而不是静态方法。 知道如何用 Scala 2(.12) 编写这段代码吗?

编辑: 上面的 java 代码 (grid.addColumn(..)) 调用了这个特定的方法:

public Column<T> addColumn(ValueProvider<T, ?> valueProvider) {
        BiFunction<Renderer<T>, String, Column<T>> defaultFactory = getDefaultColumnFactory();
        return addColumn(valueProvider, defaultFactory);
    }

引用:https://github.com/vaadin/flow-components/blob/2f6bce42b67651fd47d202fa83d8359c619fe099/vaadin-grid-flow-parent/vaadin-grid-flow/src/main/java/com/vaadin/flow/component/grid/Grid.java#L1625

最佳答案

这取决于方法的形式,在某些情况下,还取决于您使用的 Scala 版本。 Scala 3 对方法的工作方式进行了一些非常重要的更改,因此某些语法的工作方式有所不同。

假设我们有这些签名。

def foo(n: Int): Int
def bar(a: Int, b: String): Int
def baz(): Int
def frobnicate: Int

首先,如果您在 Scala 3 中并且该方法采用强制参数,那么您可以简单地使用 . 并将该方法作为一流对象获取。因此,对于以下每种方法,您都可以使用此技巧。

在这种情况下,myInstance.foo 是一个参数的函数,而 myInstance.bar 是两个参数的函数。你不能将这个技巧用于零参数的函数,即使在 Scala 3 中也是如此。

另一方面,如果该方法没有参数,或者如果您正在使用 Scala 2(在该语法最终确定之前出现),那么您可以通过放置下划线(不是在括号中)之后。例如,foo _ 在 Scala 2 和 3 中都是一个参数的函数。bar _ 是两个参数的函数,而 baz _ 是零参数的函数。 frobnicate _ 是一种用于 Scala 2 的语法,但它不再适用于在 Scala 3 中声明没有括号的零参数函数。在 Scala 3 中此类函数,您必须将它们包装在显式 lambda 中。

您还可以(对于接受一个或多个参数的函数)在参数位置明确放置下划线。有时这更具可读性,如果有多个不同参数的重载,则需要这样做。所以,在 Scala 2 和 3 中,foo(_) 是一个参数的函数,而 bar(_, _) 是两个参数的函数,我们可以甚至 部分应用 bar 作为 bar(0, _)bar(_, "")

总而言之,假设此答案顶部列出的签名:

<表类="s-表"> <头> 代码 Scala 2 行为 Scala 3 行为 <正文> obj.foo 错误 (Int) -> Int obj.bar 错误 (Int, String) -> Int obj.baz 调用baz() 错误 对象.frobnicate 调用 frobnicate 调用 frobnicate obj.foo _ (Int) -> Int (Int) -> Int obj.bar _ (Int, String) -> Int (Int, String) -> Int obj.baz _ () -> Int () -> Int 对象.frobnicate _ () -> Int 错误 obj.foo(_) (Int) -> Int (Int) -> Int obj.bar(_, _) (Int, String) -> Int (Int, String) -> Int () => obj.baz() () -> Int () -> Int () => obj.frobnicate () -> Int () -> Int

所以如果你想最大程度地向后兼容,那么最安全的做法是在函数名后加上一个_,如obj.foo _。这在所有情况下都有效, 零参数的 Scala 3 函数在声明时没有括号(即我们示例中的 frobnicate)。对于那些,你需要一个明确的 lambda,如 () => obj.frobnicate

关于scala - Scala 中等效的 Java 双冒号 (::) 运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73955857/

相关文章:

java - 我的 kafka 下载中的 SBT 文件在哪里?

java - Logback MDC put() 可变对象

vaadin - 输入 vaadin 10 TextField 的新闻事件

scala - 找到“;' expected but ' 导入”-Scala 和 Spark

scala - cassie 与 cassandra 2.0.1 和 scala 2.10.2 的依赖关系

java - 通过 Spring Boot 和 Vaadin 传播代码更​​改,无需在 Eclipse 中重新启动应用程序

java - 样式标签字体大小

node.js - 新的Vaadin 14应用程序无法运行,错误 "Failed to determine ' Node 的工具。“缺少Node.js和npm工具

javascript - Vaadin Flow - 如何添加自定义图标集?

algorithm - Scala 快速排序