【问题标题】:Make Java Consumer accept Kotlin lambda让 Java Consumer 接受 Kotlin lambda
【发布时间】:2021-06-16 05:43:34
【问题描述】:

这可能是一个奇怪的问题,但我想知道是否有人对此有一些想法。 我正在开发一个我们希望与 Java、Groovy 和 Kotlin 兼容的 DSL。我正在将 Kotlin 兼容性添加到当前代码库中,尝试尽可能少地重复。除了使用 Java Consumer 功能接口用 Groovy 编写的一小段代码外,它运行良好:

PromptOptionals prompts(Consumer<PromptOptionals> definition) {
  DefaultPromptOptionals promptOptionals = new DefaultPromptOptionals()
  definition.accept(promptOptionals)
  prompts = promptOptionals.prompts
  promptOptionals
}

这个 prompts() 方法可以从 Java/Groovy 很好地调用,但是当我用 Kotlin 调用它时:

prompts {
  say("test")
  pause(10)
  play("http://someserver.com/file")
}

3 个方法调用 say、pause 和 play 被添加到列表 promptOptionals.prompts 中,一切都按预期进行。但是对于 Kotlin,当定义.accept(promptOptionals) 被调用时,方法永远不会添加到列表中,返回的 promptOptionals 变量只是空的。 有什么方法可以让 Consumer 与 Kotlin lambda 兼容?

【问题讨论】:

    标签: java kotlin groovy functional-programming dsl


    【解决方案1】:

    当然我对你的 api 没有信心,但对我来说,忽略 lambda 的参数看起来很奇怪。也许你应该写:

    prompts { prompt ->
      prompt.say("test")
      prompt.pause(10)
      prompt.play("http://someserver.com/file")
    }
    

    【讨论】:

    • 你是对的,就是这样!比我预期的更容易解决......虽然我很好奇修复不需要显式参数的语法会有多痛苦,因为这是我们的 Groovy 等价物:prompts { say 'test' pause 10 play 'http://someserver.com/file' }
    • 不幸的是,这对 Java 来说是不可能的,但对 Kotlin 来说却很容易。你可以在你的 lambda kotlinlang.org/docs/… 中使用接收器参数。抱歉,我不知道它是否仍然适用于 Groovy
    • @claxtastic 在 groovy 中,由于我假设您的代码中的委托,这有效吗?上面的代码应该使用隐含的it?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-17
    • 1970-01-01
    • 2018-11-28
    • 1970-01-01
    • 2022-11-22
    • 2012-11-28
    相关资源
    最近更新 更多