Groovy Global Closure无法在嵌套方法调用中工作

时间:2013-08-05 06:42:15

标签: groovy scope closures

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

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

1 个答案:

答案 0 :(得分:4)

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

Groovy将上述内容转换为:

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

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

正如您所看到的,Closure是隐式run方法的本地方法,但nested方法属于类...

我相信你有3种选择:

  1. 使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()
    
  2. 写一个合适的班级并自己控制范围

    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()
        }
    }
    
  3. @groovy.transform.Field之前添加def benchmark = {name,closure -> ...这会将关闭定义移至property of this Script class

    @groovy.transform.Field 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()