Groovy全局闭包在嵌套方法调用中不起作用

Groovy全局闭包在嵌套方法调用中不起作用,groovy,scope,closures,Groovy,Scope,Closures,我有一个简单的闭包,我希望能够在我的代码中使用它来度量任何其他闭包所需的时间。看起来是这样的: def benchmark = {name,closure -> start = System.currentTimeMillis() ret = closure.call() now = System.currentTimeMillis() println(name + " took: " + (now - start)) ret } benchmar

我有一个简单的闭包,我希望能够在我的代码中使用它来度量任何其他闭包所需的时间。看起来是这样的:

def benchmark = {name,closure ->
    start = System.currentTimeMillis()
    ret =  closure.call()
    now = System.currentTimeMillis()   println(name + " took: " +  (now - start))
    ret
}
benchmark('works') { println("Hello, World\n")}
当从同一范围调用它时,它会工作,如下所示:

def benchmark = {name,closure ->
    start = System.currentTimeMillis()
    ret =  closure.call()
    now = System.currentTimeMillis()   println(name + " took: " +  (now - start))
    ret
}
benchmark('works') { println("Hello, World\n")}
但当调用嵌套范围时,它似乎不起作用

def nested()
{
   benchmark('doesnt_work'){print("hello")}
}

nested()

那是因为你在脚本中运行它

Groovy将上述内容转换为:

class Script {
    def run() {
        def benchmark = {name,closure -> ...
        nested()
    }

    def nested() {
        benchmark('doesnt_work'){print("hello")}
    }
}
如您所见,闭包是隐式
run
方法的局部闭包,但是
nested
方法属于类

我相信你有3个选择:

  • nested
    设为闭包,它们将同时存在于同一范围内

    def benchmark = {name,closure ->
        start = System.currentTimeMillis()
        ret =  closure.call()
        now = System.currentTimeMillis()
        println(name + " took: " +  (now - start))
        ret
    }
    
    def nested = {
       benchmark('doesnt_work'){print("hello")}
    }
    
    nested()
    
  • 编写一个合适的类并自己控制范围

    class Test {
        def benchmark = {name,closure ->
            long start = System.currentTimeMillis()
            def ret =  closure.call()
            long now = System.currentTimeMillis()
            println(name + " took: " +  (now - start))
            ret
        }
    
        def nested() {
            benchmark('doesnt_work'){print("hello")}
        }
    
        static main( args ) {
            new Test().nested()
        }
    }
    
  • def benchmark={name,closure->…
    之前添加
    @groovy.transform.Field
    ,这将把闭包定义向上移动为


  • 使用字段选项,因为它不会以其他方式干扰脚本流