从 Kotlin 调用需要 Function 参数的 Java 方法

From Kotlin call Java method requiring Function parameter

我在将这块 Java 转换为 Kotlin 时遇到问题:

Publishers.map(chain.proceed(request), response -> {
            if (request.getCookies().contains("SOME_VALUE")) { 
                response.cookie(request.getCookies().get(STATE_COOKIENAME).maxAge(0));
            }
            return response;
        });

map方法的第二个参数(注意Publishers不是集合)取Function<T,R>。 我尝试了几种解决方案,包括这样提供一个 lambda:

Publishers.map(chain?.proceed(request), {
        x: MutableHttpResponse<*>!,
        y: MutableHttpResponse<*>! -> print("It worked")
    })

但这会导致:

Error:(32, 38) Kotlin: Unexpected token

Error:(33, 38) Kotlin: Unexpected token

Error:(31, 27) Kotlin: Type inference failed: fun map(publisher: Publisher!, mapper: Function!): Publisher! cannot be applied to (Publisher>!>?,(MutableHttpResponse<>, MutableHttpResponse<*>) -> Unit)

Error:(31, 56) Kotlin: Type mismatch: inferred type is (MutableHttpResponse<>, MutableHttpResponse<>) -> Unit but Function>!, MutableHttpResponse<>?>! was expected

并提供方法:

return Publishers.map(chain?.proceed(request), ::processCookie)

private fun processCookie(a: MutableHttpResponse<*>?) {
   print("something something something")
}

这导致:

Error:(31, 27) Kotlin: Type inference failed: fun map(publisher: Publisher!, mapper: Function!): Publisher! cannot be applied to (Publisher>!>?,KFunction1<@ParameterName MutableHttpResponse<>?, Unit>)

Error:(31, 56) Kotlin: Type mismatch: inferred type is KFunction1<@ParameterName MutableHttpResponse<>?, Unit> but Function>!, MutableHttpResponse<*>?>! was expected

对于上下文,我认为在 kotlin 中尝试 this tutorial 会很有趣。

您没有在 lambda 中指定 return 类型,它是由 Kotlin 推断的。最后一个例子没有成功,因为函数的return类型是Unit,也就是Java中的void。我会尝试以下操作:

return Publishers.map(chain?.proceed(request), ::processCookie)

private fun processCookie(a: MutableHttpResponse<*>?) : MutableHttpResponse<*>? {
   print("something something something")
   return a
}

也可以
return Publishers.map(chain?.proceed(request)) { 
  print("something something something")
  it
}

我们在这里使用 Kotlin 中 Lambda 的默认参数名称 - 即 it。 Kotlin 编译器将为您推断类型。在 Kotlin 中也允许将函数的最后一个 lambda 参数移到方括号之外。

Java 中功能接口的最后一件事,例如Function<T,R>。您可能需要明确使用该名称,例如

return Publishers.map(chain?.proceed(request), Function<T,R> { 
  print("something something something")
  it
})

其中 TR 必须替换为实际类型