Неявное преобразование типа groovy для перехода к фиксированному не Groovy методу
Я пишу Scala-приложение, которое загружает Groovy "плагины" классы во время выполнения. Как только плагины загружены, стандартные типы Scala (например, List
а также Option
) передаются в них для обработки.
Groovy, естественно, не имеет синтаксического сахара для типов скалы (особенно Function*
семья), но я хотел бы подобный простой синтаксис. Лучшее, что у меня есть сейчас, это использовать as
Оператор для принудительного выполнения заводных замыканий в типах scala, например:
List<String> list = ... // Scala list
list.map({ it.toUpperCase() } as Function1<String,String>)
Было бы неплохо не включать as ...
хвост каждый раз, как он больше, чем фактическое закрытие.
В этом вопросе предлагается изменить метод получения, чтобы он не указывал тип параметра, однако это работает только тогда, когда вы можете использовать метод 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)
Заранее спасибо!
-Rohan
1 ответ
Я проверил байт-код функции Scala, производимой Function1, и это интерфейс, но далеко не единственный с абстрактным методом. Это означает, что он бесполезен для преобразования SAM, т.е. Java 8 не сможет использовать лямбда-выражения для автоматического преобразования в это. Я также проверил AbstractFunction1, и хотя он является абстрактным классом, у него нет абстрактного метода, так что он бесполезен даже для расширенного преобразования SAM, как это делает Groovy.
Единственное решение, которое я вижу, - написать модуль расширения, который выполняет преобразование.
РЕДАКТИРОВАТЬ: Может быть, https://github.com/scala/scala-java8-compat может помочь. Он нацелен на разрешение лямбда-кода java8 для scala FunctionN, что также позволило бы преобразование SAM для открытых блоков в случае Groovy 2.2.0 +