gpt4 book ai didi

java - 尽管 lambda 的返回类型,但 `thenApply()` 与 `thenCompose()` 不明确的情况是什么?

转载 作者:行者123 更新时间:2023-11-29 06:50:58 29 4
gpt4 key购买 nike

我正在学习 CompletableFuture

我不是在问 the difference between thenApply() and thenCompose() . 相反,我想问一下感觉不对的代码“气味”,以及什么可能真正证明它是合理的。

从我目前看到的 CompletableFuture 的用法来看,你似乎永远不会有这个:

CompletableFuture<String> foo = getSomething().thenApply((result) -> { ... });

也不是这个:

String foo = getSomething().thenCompose((result) -> { ... });

要返回 future ,您必须使用 thenCompose(),否则使用 thenApply()

虽然从经验来看,语言没有设计出一种方法来消除每次都做出这种明确的选择,这似乎很奇怪。例如,难道不能有一个方法 thenDo() 其返回类型是从 lambda 中的 return 推断出来的(在编译期间)?然后它也可以在编译时被赋予 thenApplythenCompose 之类的属性。

但我确信有一个很好的理由使用单独的方法,所以我想知道为什么。

  • 是因为在 Java 中从 lambda 推断返回类型是危险的还是不可能的? (我也是 Java 新手。)

  • 是不是因为存在单一方法确实会产生歧义的情况,唯一的解决办法就是有单独的方法? (我想可能是嵌套的 CompletableFuture 或复杂的接口(interface)和泛型。)如果是这样,有人可以提供一个明确的例子吗?

  • 是出于其他原因还是记录在案的建议?

最佳答案

作为引用,这两个方法的签名是:

<U> CompletableFuture<U>   thenApply(Function<? super T,? extends U> fn)
<U> CompletableFuture<U> thenCompose(Function<? super T,? extends CompletionStage<U>> fn)

Function<? super T,? extends U>Function<? super T,? extends CompletionStage<U>>Function<? super T, ?>作为一个常见的父类(super class)型(好吧,技术上它只是 Function )。

因此thenDo的签名会是这样的:

<U> CompletableFuture<U> thenDo(Function<? super T,?> fn)

虽然合法,但使用起来真的很痛苦,因为编译器无法检查 fn 的返回类型是否正确。是正确的,必须接受任何东西。

另外,这个 thenDo 的实现别无选择,只能apply函数并检查返回的对象是否为implements CompletionStage ,这(除了缓慢和......令人反感的不雅之外)在非直接的情况下会有真正的问题:打电话时会发生什么 thenDoCompletableFuture<CompletionStage<String>> 上?


如果您是 java 泛型的新手,我的建议是首先集中精力理解两件事:

  1. 类型参数的协变/逆变(或者说没有)。为什么不是 List<String> List<Object> 的子类型? List<Object> 之间有什么区别?和 List<?>
  2. 类型删除。为什么我不能重载基于泛型参数的方法?

完成这些设置后,研究如何通过反射解析类型变量(例如:了解 Guava 的 TypeToken 是如何工作的)


编辑:修复了一个链接

关于java - 尽管 lambda 的返回类型,但 `thenApply()` 与 `thenCompose()` 不明确的情况是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48350579/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com