2013-07-15 12 views
5

Myślę, że to prosta odpowiedź, ale moje wyszukiwanie sieci nie może go znaleźć.Zadzwoń do najwyższego poziomu funkcji z groovy metody

Jeśli mam następujące (ideone):

def f() {} 

class C 
{ 
    public h() { f() } 
} 

x = (new C()).h(); 

to się nie powiedzie z powodu następującego błędu:

No signature of method: c.f() is applicable for argument types:() values: [] 

Jak mogę zadzwonić f() z wnętrza metody C?

Odpowiedz

6

trzeba odniesienie do klasy "zewnętrznej" (która tak naprawdę nie jest klasą zewnętrzną).

Zakładając, że piszesz swój kod w pliku Script.groovy, generuje dwie klasy: C.class i Script.class. Nie ma sposobu na wywołanie metody C, ponieważ nie ma ona pojęcia, gdzie jest zdefiniowana.

Masz kilka opcji:

1) @ idei MichaelEaster użytkownika, dając defition metaklasa z bieżącego zakresu (tj Script)

2) Tworzenie/zdać Script obiekt wewnątrz C:

def f() { "f" } 

class C 
{ 
    public h(s = new Script()) { s.f() } 
} 

assert "f" == new C().h() 

3) Bądź C klasa wewnętrzna (który również potrzebuje wystąpienie Script:

class Script { 
    def f() { "f" } 

    class C 
    { 
     public h() { f() } 
    } 

    static main(args) { 
    assert "f" == new C(new Script()).h() 
    } 
} 

4) statyczna klasa wewnętrzna oraz statyczne f(): odpowiedź

class Script { 
    static def f() { "f" } 

    static class C 
    { 
     public h() { f() } 
    } 

    static main(args) { 
    assert "f" == new C().h() 
    } 
} 
+0

Plus @ dmahapatro za :-) – Will

+0

dobrze wyjaśnione. Nie mogę podać tego wyjaśnienia z mojego telefonu, więc zaproponowałem łatwy. ;) – dmahapatro

0

Oto jeden ze sposobów, aby to zrobić za pomocą meta-programowanie:

def f() { println "Hello" } 

class C 
{ 
    public h() { f() } 
} 

C.metaClass.f = { f() } 

x = (new C()).h(); 
2

inny sposób, bez użycia metaClass jest zdefiniowanie h() jako zamknięcie i zastosowanie:

def f() {} 
class C {  
    def h = { f() } 
} 
x = (new C()).h 
x.delegate = this 

x() 
Powiązane problemy