为什么 Flux.zip 接受预定义函数而不接受匿名函数?
Why Flux.zip accept predefined Function but not an anonymous function?
在 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报错:
Array type expected; found: 'org.reactivestreams.subscriber>.
我想知道为什么带有显式 return 的预定义函数和匿名函数可以工作但匿名函数?
感谢您的帮助。
不是编译器专家,但我认为这与 java 编译器看到短格式 lambda 的歧义有关:你传递的是内联 Publisher
(因为它是功能接口)或 Function
?
这种混淆之所以成为可能,是因为短格式没有明确的 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);
在 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报错:
Array type expected; found: 'org.reactivestreams.subscriber>.
我想知道为什么带有显式 return 的预定义函数和匿名函数可以工作但匿名函数?
感谢您的帮助。
不是编译器专家,但我认为这与 java 编译器看到短格式 lambda 的歧义有关:你传递的是内联 Publisher
(因为它是功能接口)或 Function
?
这种混淆之所以成为可能,是因为短格式没有明确的 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);