Нестандартное неявное принуждение в Groovy - PullRequest
0 голосов
/ 30 апреля 2019

Есть ли в Groovy функция, похожая на неявные преобразования в scala?

Я теперь, когда мы можем определить приведение пользовательских типов, как здесь: ссылка , но необходимо использовать ключевое слово "as" длядобавьте, чтобы использовать его.

Чтобы предоставить конкретный пример использования: я хочу создать преобразование из строки в валюту, и после его включения хочу передать строку в метод, для которого в качестве параметра требуется валюта.

public class SomeJavaClass { 
    void method(Currency currency){
    ...
    }
}

и после неявного преобразования этот код должен быть действительным:

class SomeGroovyClass {
    def method(){
        new SomeJavaClass().method("USD")
    }
}

Возможно ли это как-то?

1 Ответ

0 голосов
/ 01 мая 2019

Groovy не предлагает неявного принуждения, но динамические возможности языка позволяют переопределить methodMissing() для класса вызываемого (в зависимости от того, является ли метод вызываемого объекта статическим, methodMissing() или $static_methodMissing() должны быть переопределены, см. документы ):

class ShrewdCalculator {
    static void accept(Currency o) {
        println o
    }

    static def $static_methodMissing(String name, def args) {
        if (name == "accept" && args.size() == 1 && args[0].class == String) {
            return accept(Currency.valueOf(args[0]))
        }
        throw new MissingMethodException(name, this.class, args)
    }
}

, где Currency например,

enum Currency {
    US_DOLLAR, EURO

    static valueOf(String s) {
        if (s == "USD") return US_DOLLAR
        if (s == "EUR") return EURO
        throw new RuntimeException("No currency defined for input $s")
    }
}

Тогда вызов метода даст следующие результаты:

ShrewdCalculator.accept(Currency.US_DOLLAR) // --> US_DOLLAR
ShrewdCalculator.accept("USD") // --> US_DOLLAR thanks to fallback on methodMissing()

ДругойМожно добавить метод принуждения к ExpandoMetaClass класса String и просто использовать Object в сигнатуре метода только для принудительного его принудительного применения:

class ShrewdCalculator {
    static {
        String.metaClass.asType(Currency) {
            return Currency.valueOf(this)
        }
    }

    static void accept(Object o) {
        println o as Currency
    }
}

В этом случаеметод будет работать так:

ShrewdCalculator.accept(Currency.US_DOLLAR) // --> US_DOLLAR because Currency as Currency is no-op
ShrewdCalculator.accept("USD") // --> US_DOLLAR thanks to coercion defined in String's metaclass

Ни один из этих методов не похож на последствия Scala.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...