6

我认为这有一个简单的答案,但我的网络搜索找不到它。

如果我有以下(ideone):

def f() {}

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

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

这失败并出现以下错误:

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

如何f()从方法内部调用C

4

3 回答 3

6

You need a reference to the "outer" class (which isn't really an outer class).

Assuming you are writing your code in a Script.groovy file, it generates two classes: C.class and Script.class. There is no way to the C call the f() method, since it has no idea where it is defined.

You have some options:

1) @MichaelEaster's idea, giving a metaclass defition from the current scope (i.e. Script)

2) Create/pass a Script object inside C:

def f() { "f" }

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

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

3) Make C an inner class (which also needs an instance of Script:

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

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

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

4) Static inner class plus static f():

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

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

  static main(args) {
    assert "f" == new C().h()
  }
}
于 2013-07-15T12:17:27.580 回答
2

另一种不使用的方法metaClass是定义h()为闭包并使用:

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

x()
于 2013-07-15T12:11:01.257 回答
0

这是使用元编程的一种方法:

def f() {  println "Hello" }

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

C.metaClass.f = { f() }

x = (new C()).h();
于 2013-07-15T10:14:39.477 回答