[Groovy] 程式設計教學:使用閉包 (Closure)

【分享本文】
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

    前言

    在 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 }
    【分享本文】
    Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email
    【追蹤新文章】
    Facebook Twitter Plurk
    標籤: GROOVY, JAVA