我见过一些如何在Scala中编写::Equvalant的示例,例如将System.out::println传递给一个函数,但我不知道如何在Scala中编写这个Vaadin网格组件:
Grid<Person> grid = new Grid<>(Person.class, false);
grid.addColumn(Person::getFirstName).setHeader("First name");
grid.addColumn(Person::getLastName).setHeader("Last name");
这里的GET方法是常规的Getter方法,而不是静态方法。你知道如何用Scala2(.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
1条答案
按热度按时间0ejtzxu11#
这取决于方法的形状,在某些情况下,还取决于您正在使用的Scala版本。Scala 3对方法的工作方式做了一些非常重要的更改,因此一些语法的工作方式有所不同。
让我们假设我们已经得到了这些签名。
首先,如果您使用的是Scala3,并且该方法接受强制参数,则只需使用
.
并将该方法作为一级对象获取即可。因此,对于以下每种方法,您都可以使用此技巧。在这种情况下,
myInstance.foo
是一个参数的函数,而myInstance.bar
是两个参数的函数。即使在Scala3中,您也“不能”在零参数函数中使用此技巧。另一方面,如果方法没有参数,或者如果您使用的是Scala 2(它是在此语法最终确定之前推出的),则可以通过在方法后面加下划线(而不是在括号中)将其转换为对象。例如,
foo _
在Scala 2和3中都是一个参数的函数。bar _
是两个参数的函数,而baz _
是零参数的函数。frobnicate _
是一种在Scala 2中使用的语法,但对于在Scala 3中声明的无括号为零参数的函数,它将不再起作用。在Scala 3中,对于这类函数,您必须将它们 Package 在显式的lambda中。您还可以(对于接受一个或多个参数的函数)显式地在参数位置放置下划线。有时,这更具可读性,如果存在不同类型的多个重载,则需要这样做。因此,在Scala 2和3中,
foo(_)
是一个参数的函数,而bar(_, _)
是两个参数的函数,我们甚至可以部分应用bar
作为bar(0, _)
或bar(_, "")
总而言之,假设此答案顶部列出的签名:
Code|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 _
所示。这将在所有情况下都有效除了零参数的Scala3函数,这些函数声明时不带括号(即本例中的frobnicate
)。对于这些,您需要一个显式的lambda,如() => obj.frobnicate