如何在Groovy代码中调用Kotlin扩展函数(Gradle插件场景)
解决Kotlin Gradle插件中infix扩展函数在Groovy DSL的调用问题
问题根源
Kotlin的infix扩展函数是语言独有的语法糖,Groovy既不支持该语法,也无法直接识别Kotlin定义的成员扩展函数(仅能识别顶层扩展函数或通过Groovy官方扩展机制注册的方法),因此会出现'first'.foo('second')调用失败的情况。
方案一:注册Groovy扩展方法,支持'first'.foo('second')调用
通过Groovy的扩展模块机制,为String类型注册对应的扩展方法,映射到原Kotlin的infix扩展函数。
- 编写Groovy扩展类(用Kotlin实现即可):
package com.your.plugin.package class StringGroovyExtensions { companion object { @JvmStatic fun foo(receiver: String, other: String) { // 直接调用原Kotlin infix扩展函数 receiver foo other } } }
- 创建Groovy扩展模块配置文件
在src/main/resources/META-INF/services目录下新建文件org.codehaus.groovy.runtime.ExtensionModule,内容如下:
moduleName=my-plugin-groovy-extensions moduleVersion=1.0 extensionClasses=com.your.plugin.package.StringGroovyExtensions
- 确保配置文件被打包进插件Jar
在插件项目的build.gradle.kts中添加Jar任务配置:
tasks.jar { from("src/main/resources") { include("META-INF/services/org.codehaus.groovy.runtime.ExtensionModule") } }
完成后,Groovy DSL用户即可使用'first'.foo('second')的方式调用。
方案二:添加双参数方法,模拟first foo second的简洁调用
在你的MyPluginExtension类中新增一个双参数的foo方法,直接转发调用原infix扩展函数,利用Groovy支持省略点和括号的方法调用特性,实现类似Kotlin的简洁语法。
修改MyPluginExtension类:
open class MyPluginExtension { // Kotlin DSL用的infix扩展函数 infix fun String.foo(other: String) { println("$this -> $other") } // Groovy DSL用的双参数方法,模拟infix语法 fun foo(first: String, second: String) { first foo second } }
此时Groovy DSL用户可以直接写:
myPlugin { 'first' foo 'second' // Groovy会自动解析为调用foo('first', 'second') }
方案对比
- 方案一:调用风格更贴近Kotlin的扩展函数语法,但需要额外配置Groovy扩展模块,打包时需确保配置文件被包含。
- 方案二:无需额外配置,实现的调用语法和Kotlin的infix写法几乎一致,但本质是调用普通双参数方法,而非String的扩展方法。
内容的提问来源于stack exchange,提问作者Vadik Sirekanyan
相关产品推荐
相关产品推荐

