Natknąłem się na coś z Groovy closures i delegatów, że nie jestem pewien, jest oficjalną częścią języka, a może nawet błąd.Aby groovy zamknięcie zmodyfikować zmienną zdefiniowaną w zakresie delegata, należy jawnie określić delegate.theVariableName?
Zasadniczo definiuję zamknięcie, które odczytałem jako ciąg z zewnętrznego źródła, , a jedna ze zmiennych w klasie, która definiuje zamknięcie, musi zostać zmodyfikowana przez zamknięcie. Napisałem prosty przykład pokazujący, co znalazłem działa, a co nie działa.
Jeśli spojrzeć na kodzie testowym poniżej widać klasę, która definiuje zmienną
animal = "cat"
i dwóch zamknięć określonych w locie z ciągów znaków, które próbują modyfikować zmienną zwierząt.
Działa>
String code = "{ -> delegate.animal = 'bear'; return name + 'xx' ; }"
Ale to nie
String code = "{ -> animal = 'bear'; return name + 'xx' ; }"
Wydaje się, że muszę jednoznacznie zakwalifikować mój do-zmodyfikowaną zmienną 'delegata'. aby to działało. (Domyślam się, że można również zdefiniować program ustawiający w klasie otaczającej dla zamknięcia, aby wywołać, aby zmodyfikować wartość).
Więc .... dowiedziałem się jak to zrobić, ale byłbym zainteresowany, jeśli ktoś mógłby wskazać mi jakiś fajny dokument , który wyjaśnia zasady stojące za tym.
Konkretnie .... dlaczego będzie proste zadanie
animal = 'bear'
wpływa na zmienną oryginalnego? Czy są tu robione kopie w tle?
import org.junit.Test
/*
* Author: cbedford
* Date: 8/30/12
* Time: 1:16 PM
*/
class GroovyTest {
String animal = "cat"
String name = "fred"
@Test
public void testDelegateWithModificationOfDelegateVariable() {
String code = "{ -> delegate.animal = 'bear'; return name + 'xx' ; }"
def shell = new GroovyShell()
def closure = shell.evaluate(code)
closure.delegate = this
def result = closure()
println "result is $result"
println "animal is $animal"
assert animal == 'bear'
assert result == 'fredxx'
}
// This test will FAIL.
@Test
public void testDelegateWithFailedModificationOfDelegateVariable() {
String code = "{ -> animal = 'bear'; return name + 'xx' ; }"
def shell = new GroovyShell()
def closure = shell.evaluate(code)
closure.delegate = this
def result = closure()
println "result is $result"
println "animal is $animal"
assert animal == 'bear'
assert result == 'fredxx'
}
}
To ma sens. i też szybko; ^). wielkie dzięki. –