TiN*_*TiN 3 scala vaadin vaadin-flow
我已经看到了一些如何在 Scala 中编写 :: 等价的示例,例如将 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");
Run Code Online (Sandbox Code Playgroud)
这里的 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);
}
Run Code Online (Sandbox Code Playgroud)
这取决于方法的形式,在某些情况下,还取决于您使用的 Scala 版本。Scala 3 对方法的工作方式做了一些相当重大的改变,因此某些语法的工作方式有所不同。
假设我们已经得到了这些签名。
def foo(n: Int): Int
def bar(a: Int, b: String): Int
def baz(): Int
def frobnicate: Int
Run Code Online (Sandbox Code Playgroud)
首先,如果您使用的是 Scala 3 并且该方法采用强制参数,那么您可以简单地使用 a.并将该方法作为一等对象获取。所以对于下面的每一种方法,你都可以使用这个技巧。
在这种情况下,myInstance.foo是一个参数的函数,myInstance.bar也是两个参数的函数。即使在 Scala 3 中,也不能将这个技巧用于零参数的函数。
另一方面,如果该方法没有参数,或者如果您使用的是 Scala 2(该语法在最终确定之前就已出现),那么您可以通过放置下划线(不在括号中)将方法转换为对象在它之后。例如,foo _在 Scala 2 和 3 中, 是一个只有一个参数的函数。bar _是一个有两个参数的函数,并且baz _是一个有零个参数的函数。是一种曾经在 Scala 2 中使用的语法,但对于 Scala 3 中声明的没有frobnicate _括号的零参数函数不再适用。在 Scala 3 中,对于此类函数,您必须将它们包装在显式 lambda 中。
您还可以(对于接受一个或多个参数的函数)在参数位置显式放置下划线。有时这更具可读性,并且如果存在不同参数的多个重载,则这是必需的。因此,在 Scala 2 和 3 中,foo(_)是一个参数的函数,而bar(_, _)是两个参数的函数,我们甚至可以部分应用 bar为bar(0, _)或bar(_, "")
总之,假设此答案顶部列出的签名:
| 代码 | Scala 2 行为 | Scala 3 行为 |
|---|---|---|
obj.foo |
错误 | (Int) -> Int |
obj.bar |
错误 | (Int, String) -> Int |
obj.baz |
通话baz() |
错误 |
obj.frobnicate |
通话frobnicate |
通话frobnicate |
obj.foo _ |
(Int) -> Int |
(Int) -> Int |
obj.bar _ |
(Int, String) -> Int |
(Int, String) -> Int |
obj.baz _ |
() -> Int |
() -> Int |
obj.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