我看过一些如何在 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);
}
最佳答案
这取决于方法的形式,在某些情况下,还取决于您使用的 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(_, "")
总而言之,假设此答案顶部列出的签名:
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/