Неявное преобразование типа 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 +

Другие вопросы по тегам