【在主画面加入捷径】
       
【选择语系】
繁中 简中

[Groovy] 程序设计教学:使用闭包 (Closure)

【赞助商连结】

    在 Groovy 中,最接近函式的东西是闭包 (closure);基本上,可以把 Groovy 的闭包当成类似其他语言的匿名函式 (anonymous function) 来看待。在先前的文章中,我们其实已经看过闭包了,因 Groovy 中大量使用闭包,像是看起来很像 Ruby 语法的迭代器、串行操作、映射操作等基本上内部皆以闭包来运作。

    建立闭包

    以下范例建立一个最简单的闭包:

    // Declare a closure.
    def hello = { println "Hello World" }
    
    // Call the hello closure.
    hello()
    
    // Alternatively, explicit call
    hello.call()

    在这个范例的闭包,既没有参数,也没有回传值,基本上不太实用,只是展示如何建立闭包。

    带有参数或回传值的闭包

    以下建立一个带有两个参数的闭包:

    def add = { a, b -> a + b }
    
    assert add(3, 5) == 8

    在这个例子中,闭包 add 会将两个参数相加,然后将相加后的值回传。

    以闭包撰写递归 (Recursion)函数

    闭包本质上也是函式,所以闭包也可以撰写递归函式。以下这个例子使用递归调用:

    def fib
    fib = { int n ->
        if (n <= 1) {
            return n
        }
    
        fib(n - 1) + fib(n - 2)
    }
    
    println fib(10)

    写递归程序的重点在于终止条件和缩小步骤,由于递归在程序设计中相当重要,最好要多练习一些题目。

    以闭包撰写递归函式时,要将识别字声明及闭包实现的部分分开,因为 Groovy 需要使用该识别字撰写递归函式。以本例来说,就是 fib

    用 Memoization 加速递归函式的运算速度

    传统的递归在每次调用时都重新计算,这样比较浪费运算效能,使用 memoization 的手法可以储存先前计算的结果,加速递归运算。Groovy 内建 memoization 的支援,参考下例:

    def fib
    fib = { int n ->
    	if (n <= 1) {
    		return n
    	}
    	
    	fib(n - 1) + fib(n - 2)
    }
    
    fib = fib.memoize()
    
    println fib(10)

    利用闭包管理系统资源

    在撰写 Java 程序时,需要手动将文件等系统资源 (system resources) 释放,而 Groovy 的闭包可自动处理这个问题,如以下例子:

    new File('file.txt').eachLine { println it }
    TAGS: GROOVY, JAVA