从Groovy方法调用顶层函数

7
我觉得这个问题的答案很简单,但是我在网上搜索时没有找到它。
如果我有以下内容(ideone):
def f() {}

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

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

这个出现了以下错误:

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

如何从 C 的方法内部调用 f()
3个回答

5
您需要一个对于“外部”类的引用(实际上不是一个外部类)。
假设您在一个名为 Script.groovy 的文件中编写代码,它会生成两个类:C.classScript.class。由于它不知道定义在哪里,所以没有办法使 C 调用 f() 方法。
您有几个选择: 1) 使用 @MichaelEaster 的方法,在当前作用域(即 Script)中给出元类定义。 2) 创建/传递一个 Script 对象到 C 中:
def f() { "f" }

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

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

3)C 设为内部类(它还需要一个Script实例):

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

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

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

4) 静态内部类加上静态f()

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

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

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

另外加上@dmahapatro的答案 :-) - Will
讲解得很清楚。我几乎无法从手机上进行这样的解释,因此我提出了一个简单的解释。;) - dmahapatro
作为一个特例,如果你正在使用Jenkins和Groovy脚本来使用Pipeline插件,你可以通过DSL对象查找方法,如果你传递了对调用管道的引用。你使用与从类中访问任何其他步骤相同的方法。 - Craig Ringer
1
脚本是一个抽象类,不能被实例化。 - Zachary Chiodini

2

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

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

x()

1
这是一种使用元编程的方法,可以这样做:

def f() {  println "Hello" }

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

C.metaClass.f = { f() }

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接