Подтвердить что ты не робот

Groovy Итерация свойств

В приведенном ниже коде Groovy я заменяю значения свойств feck, arse, drink экземпляра Foo экземплярами экземпляра 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"
}

Есть ли лучший способ сделать это? Моя особая проблема с приведенным выше кодом заключается в том, что имена свойств хранятся в виде строк в списке, которые, вероятно, будут пропущены, когда (например) с помощью среды рефакторинга для изменения одного из этих имен свойств.

4b9b3361

Ответ 1

Я еще не нашел хороший подход для исключения свойств только для чтения (т.е. metaClass, class), но если вы хотите установить значение всех свойств в экземпляре Foo, которые также находятся в экземпляре 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()


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"

Ответ 2

Очень поздний ответ... однако, что взять только не синтетический 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, сообщающее, что что-то не так.