为啥 Flux.zip 接受预定义函数而不接受匿名函数?
Posted
技术标签:
【中文标题】为啥 Flux.zip 接受预定义函数而不接受匿名函数?【英文标题】:Why Flux.zip accept predefined Function but not an anonymous function?为什么 Flux.zip 接受预定义函数而不接受匿名函数? 【发布时间】:2020-04-12 00:34:55 【问题描述】:在java
学习Flux(reactive-core)时,遇到以下关于Function的问题。
这是Flux.zip()
方法签名:
public static <I, O> Flux<O> zip(
final Function<? super Object[], ? extends O> combinator,
Publisher<?extends I>... sources)
return zip(combinator, Queues.XS_BUFFER_SIZE, sources);
当我尝试调用此方法时:
Flux<User> userFluxFromStringFlux(Flux<String> usernameFlux, Flux<String> firstnameFlux, Flux<String> lastnameFlux)
// predefined function taking object[] and returns User
Function<Object[], User> function = array -> new User(array[0].toString(),array[1].toString(), array[2].toString());
// it is working without error
Flux.zip(function, usernameFlux, firstnameFlux, lastnameFlux);
// this is also working without error
Flux.zip(array ->
return new User(array[0].toString(),array[1].toString(), array[2].toString());
, usernameFlux, firstnameFlux, lastnameFlux);
// but this has error with array[0] "Array type expected; found: 'org.reactivestreams.subscriber<capture<? super java.lang.object>>'"
Flux.zip(array -> new User(array[0].toString(),array[1].toString(), array[2].toString()), usernameFlux, firstnameFlux, lastnameFlux);
return null;
第三种方式使用匿名函数,但IDEA报错:
预期的数组类型;找到:'org.reactivestreams.subscriber>。
我想知道为什么预定义的函数和具有显式返回的匿名函数可以工作,但匿名函数?
感谢您的帮助。
【问题讨论】:
【参考方案1】:不是编译器专家,但我认为这与 java 编译器看到短格式 lambda 的歧义有关:是您传递的内联 Publisher
(因为它是一个功能接口)或 @987654322 @?
这种混淆是可能的,因为简短形式没有明确的return
语句:在Publisher
选项的情况下,这意味着您创建一个User
以立即被垃圾收集,但这不是编译器会禁止你做的事情。
所以 lambda 的目标类型被假定为Publisher
,因此array
被推断为Subscriber
。但是后面用了数组索引操作符,肯定是错的。
另一方面,将
放入括号中,可以通过明确的 return
类型在推理中使用来消除这种歧义。对于编译器,您不能再代表 Publisher
,因此使用下一个候选者 (Function
)。
消除歧义的另一种方法是向编译器显示array
是...一个数组:
Flux.zip((Object[] array) -> new User(array[0].toString(),array[1].toString(), array[2].toString())
, usernameFlux, firstnameFlux, lastnameFlux);
【讨论】:
以上是关于为啥 Flux.zip 接受预定义函数而不接受匿名函数?的主要内容,如果未能解决你的问题,请参考以下文章