Groovy именованные и аргументы по умолчанию - PullRequest
5 голосов
/ 14 сентября 2011

Groovy поддерживает как стандартные, так и именованные аргументы. Я просто не вижу их совместной работы.

Мне нужны некоторые классы для поддержки построения с использованием простых неименованных аргументов и с использованием именованных аргументов, как показано ниже:

def a1 = new A(2)
def a2 = new A(a: 200, b: "non default")

class A extends SomeBase {
    def props
    A(a=1, b="str") { 
        _init(a, b)
    }

    A(args) { 
       // use the values in the args map:
       _init(args.a, args.b)
       props = args
    }

    private _init(a, b) {
    }

}

Является ли вообще хорошей практикой поддержка обоих одновременно? Является ли приведенный выше код единственным способом?

1 Ответ

6 голосов
/ 14 сентября 2011

Данный код вызовет некоторые проблемы.В частности, он сгенерирует два конструктора с одним параметром Object.Первый конструктор генерирует байт-код, эквивалентный:

A() // a,b both default
A(Object) // a set, b default
A(Object, Object) // pass in both

Второй генерирует это:

A(Object) // accepts any object

Вы можете обойти эту проблему, добавив некоторые типы.Несмотря на то, что groovy имеет динамическую типизацию, объявления типов в методах и конструкторах по-прежнему имеют значение.Например:

A(int a = 1, String b = "str") { ... }
A(Map args) { ... }

Что касается хороших практик, я бы просто использовал одну из аннотаций groovy.transform.Canonical или groovy.transform.TupleConstructor.Они автоматически предоставят правильную карту свойств и конструкторы позиционных параметров.TupleConstructor предоставляет только конструкторы, Canonical применяет некоторые другие рекомендации в отношении equals, hashCode и toString.

...