web-dev-qa-db-ja.com

Groovyプロパティの反復

以下のGroovyコードでは、feckのインスタンスのarsedrinkFooプロパティの値をFoo2のインスタンスの値に置き換えます。

class Foo {
    def feck = "fe"
    def arse = "ar"
    def drink = "dr"    
}

class Foo2 {

    def feck = "fe2"
    def arse = "ar2"
    def drink = "dr2"
}


def f = new Foo()
def f2 = new Foo2()


["feck", "arse", "drink"].each {it ->
    f."$it" = f2."$it"
}

これを行うためのより良い方法はありますか?上記のコードに関する私の特定の懸念は、プロパティ名がリストに文字列として格納されることです。これは、(たとえば)リファクタリングIDEを使用してこれらのプロパティ名の1つを変更する場合に見落とされる可能性があります) 。

28
Dónal

読み取り専用プロパティ(つまり、metaClass、class)を除外するための適切なアプローチはまだ見つかりませんが、Foo2インスタンスにもあるFooインスタンスのすべてのプロパティの値を設定する場合は、以下。

class Foo {
    def feck = "fe"
    def arse = "ar"
    def drink = "dr"    
}

class Foo2 {

    def feck = "fe2"
    def arse = "ar2"
    def drink = "dr2"
}


def f = new Foo()
def f2 = new Foo2()


f2.properties.each { prop, val ->
    if(prop in ["metaClass","class"]) return
    if(f.hasProperty(prop)) f[prop] = val
}

assert f.feck == "fe2"
assert f.arse == "ar2"
assert f.drink == "dr2"
30

非常に遅い答え...しかし、declaredFieldsクラスの非合成Fooだけを取るのはどうでしょうか。あなたのアプローチを使用して:

class Foo {
    def feck = "fe"
    def arse = "ar"
    def drink = "dr"    
}

class Foo2 {
    def feck = "fe2"
    def arse = "ar2"
    def drink = "dr2"
}


def f = new Foo()
def f2 = new Foo2() 

Foo.declaredFields.findAll { !it.synthetic }*.name.each {it ->
    f[it] = f2[it]
}

assert f.feck == "fe2"
assert f.arse == "ar2"
assert f.drink == "dr2"

たとえばFooで何か変更をリファクタリングするが、Foo2では変更しない場合、このコードからExceptionがスローされ、何かが間違っていることを通知します。

8
albciff