Call top level function from groovy method

戏子无情 提交于 2021-02-07 13:29:05

问题


I figure this has a simple answer, but my web searching couldn't find it.

If I've got the following (ideone):

def f() {}

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

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

This fails with the following error:

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

How do I call f() from inside a method of C?


回答1:


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()
  }
}



回答2:


Another way, without using metaClass is to define h() as a closure and use:

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

x()



回答3:


Here is one way to do it, using meta-programming:

def f() {  println "Hello" }

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

C.metaClass.f = { f() }

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


来源:https://stackoverflow.com/questions/17651114/call-top-level-function-from-groovy-method

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!