隐式转换 groovy 类型以传递给固定的 non-groovy 方法

Implicitly convert groovy type to pass to a fixed non-groovy method

我正在编写一个 scala 应用程序,它在运行时加载 Groovy "plugin" 类。加载插件后,标准 scala 类型(如 ListOption)将被传递给它们进行处理。

Groovy 自然没有 Scala 类型(特别是 Function* 系列)的语法糖,但我想要一个类似的简单语法。我现在最好的办法是使用 as 运算符将 groovy 闭包强制转换为 scala 类型,例如:

List<String> list = ... // Scala list
list.map({ it.toUpperCase() } as Function1<String,String>)

最好不要每次都包含 as ... 尾巴,因为它比实际闭包大。

This 问题建议将接收方法更改为不指定参数类型,但是只有当它是您可以控制的 groovy 方法时才有效。我正在使用编译 scala/java 类.

我知道在 Groovy 中有多种方法可以隐式转换内容,但是有许多独立的小 groovy 脚本被独立加载。我不太了解 groovy 以了解哪种机制最适合这种体系结构,以便所有加载的插件都能以最少的仪式和导入获得这种隐式转换。我有大约 50 多个插件,所以简化这个 scala/groovy 互操作对我来说是值得的。

这是我如何加载 groovy 脚本的简化版本(其中 Plugin 是我的一种类型):

// Created once
val currentClassLoader = this.getClass.getClassLoader
val groovyClassLoader = new GroovyClassLoader(currentClassLoader)

...

// Many plugins created this way
val pluginFile = new java.io.File("path/to/some/plugin/MyPlugin.groovy")
val plugin: Plugin = groovyClassLoader.parseClass(pluginFile).asInstanceOf[Plugin]

// Use it
val list = List(1,2,3)
val answer = plugin.process(list)

提前致谢!

-洛汗

我检查了 Function1 scala 生成的字节码,它是一个接口,但到目前为止还没有一个具有单一抽象方法的接口。这意味着它对 SAM 转换没有用,即。 Java 8 将无法使用 lambda 自动转换为该值。我还检查了 AbstractFunction1,虽然它是一个抽象 class,但它没有抽象方法,因此即使像 Groovy 那样对扩展 SAM 转换也无用。

我看到的唯一解决方案是编写一个 extension module 来进行转换。

编辑:也许 scala-java8-compat 可以提供帮助。它的目标是允许 java8 scala FunctionN 的 lambdas,这也将允许在 Groovy 2.2.0 +

的情况下对开放块进行 SAM 转换