2011-09-14 60 views
4

Groovyは、デフォルト引数と名前付き引数の両方をサポートしています。私は彼らが一緒に働くのを見ていない。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) { 
    } 

} 

同時に両​​方をサポートするために、一般的に良い練習ですか?上記のコードはそれに唯一の方法ですか?

答えて

6

このコードではいくつかの問題が発生します。特に、1つのObjectパラメータを持つ2つのコンストラクタを生成します。最初のコンストラクタはバイトコードに相当を生成します。

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に関して他のベストプラクティスを適用します。

関連する問題