2

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

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

1 回答 1

5

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

Groovy 将上述内容转换为:

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

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

如您所见,闭包是隐式方法的本地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 -> ...会将闭包定义向上移动到此 Script 类的属性

    @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()
    
于 2013-08-05T08:06:19.760 回答