0

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

Groovy 自然没有 scala 类型(尤其是Function*家族)的语法糖,但我想要一个类似的简单语法。我现在最好的方法是使用as运算符将​​常规闭包强制转换为 scala 类型,例如:

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

不必as ...每次都包含尾巴会很好,因为它比实际的闭合要大。

这个问题建议将接收方法更改为不指定参数类型,但是只有当它是您可以控制的常规方法时才有效。我正在使用编译的 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)

提前致谢!

-罗汉

4

1 回答 1

0

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

我看到的唯一解决方案是编写一个进行转换的扩展模块

编辑:也许scala-java8-compat可以提供帮助。它的目标是允许 scala FunctionN 的 java8 lambdas,这也将允许在 Groovy 2.2.0 + 的情况下对开放块进行 SAM 转换

于 2015-05-20T16:01:04.783 回答