java - 如何使用方法引用运算符(::) 在供应商函数中传递参数
问题描述
抱歉,这在函数式编程中似乎非常基础,但我不明白这个想法。实际上我的代码中有一个方法,它使用一个方法和另一个参数作为参数。
private <R> CompletableFuture<R> retryRequest(Supplier<CompletableFuture<R>> supplier, int maxRetries)
我想调用这个函数并传递另一个方法(anOtherMethod),它采用一个整数参数:
CompletableFuture<Boolean> retry = this.retryRequest(this:: anOtherMethod, 2);
没有得到这个我怎么能调用这个retryRequest并给出anOtherMethod(123)?
我知道它可以像这样工作:
CompletableFuture<Boolean> retry = this.retryRequest(()-> anOtherMethod(123), 2);
解决方案
您不能像123
在纯方法引用变体中那样使用特定的捕获值来实例化 lambda。. 如果要传递捕获的值而不是实例来执行方法,则需要使用箭头编写显式 lambda 版本。在此答案中阅读有关在 lambda 中捕获值的更多信息:增强的“for”循环和 lambda 表达式
唯一的例外是对象,它本身成为第一个参数。假设一个签名需要一个字符串的消费者:
public void something(Consumer<String> job) {
...
上面的签名将使您能够编写以下调用:
String myString = " Hey Jack ";
something(myString::trim);
something(s -> s.trim());
两者都做同样的事情,这可能是不直观的,因为一个接受一个参数(实例引用myString
)而一个似乎没有(但它实际上也是如此)。这是可行的,因为编译器为 lambda 方法引用尝试了两种可能的解决方案(上面带有 的版本::
)。一方面,编译器可以应用签名,就好像被调用的方法没有任何参数,也不需要传递。对于myString.trim
. 但是编译器也会检查是否有静态方法String.trim(myString)
(幸运的是没有)。如果您想调用不带任何参数的静态方法,则必须使用函数引用调用类标识符,如下所示:
something(String::trim); // this version of trim does not exist.
这有时甚至是一个问题,因为如果一个类提供了一个方法的静态版本和一个与实例相关的方法,你就会变得模棱两可:
public void somethingElse(Function<Integer, String> transformation) {...}
// This will not compile:
somethingElse(Integer::toString);
上面的例子不会编译,因为该toString
方法存在两次,一次是静态的Integer.toString(someInt)
,一次是实例相关someInteger.toString()
的。
推荐阅读
- azure - 记住 Azure Active Directory Xamarin Forms 中上次登录的用户
- ios - 发布模式下的离子应用程序显示白屏
- bash - 如何测试 bats-assert 框架中是否设置了环境变量?
- azure - 将客户端应用程序添加到 Azure AD 应用程序会引发错误
- rust - 在 Rust 中,如何将发散函数作为参数传递给另一个函数
- node.js - 从 req.params.foo 查询参数到 mongoose find() 不起作用或返回空数组
- highcharts - 获取页面以匹配 highcharts 样式
- embedded-linux - imx6ul - 如何为 sdcard 图像选择正确的 dts?
- python - 如何为多个用户提供持续运行的 python 脚本(社交媒体机器人)
- clion - 如何触发对具有与检查功能相同签名的自定义功能的现有检查?