隐式转换 groovy 类型以传递给固定的 non-groovy 方法
Implicitly convert groovy type to pass to a fixed non-groovy method
我正在编写一个 scala 应用程序,它在运行时加载 Groovy "plugin" 类。加载插件后,标准 scala 类型(如 List
和 Option
)将被传递给它们进行处理。
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 转换
我正在编写一个 scala 应用程序,它在运行时加载 Groovy "plugin" 类。加载插件后,标准 scala 类型(如 List
和 Option
)将被传递给它们进行处理。
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 转换