为啥 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 接受预定义函数而不接受匿名函数?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 evbuffer_add_printf 只接受静态变量而不接受“动态”变量?

为啥我的 GPU 拒绝接受共享内存配置而不发出错误?

为啥这个 OCaml 定义被错误的类型接受?

为啥函数 c() 接受未记录的参数?

html 输入 onchange 不接受匿名函数

为啥 MPI_Init 接受指向 argc 和 argv 的指针?