[Groovy] 程式設計教學:撰寫和使用函式 (Function)

【分享本文】
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email
【贊助商連結】

    在 Java 中,函式 (function) 一定要包在類別中,所以才會出現靜態函式這種和物件無關但又存在於類別中的函式。在 Groovy 中,這個限制放寛了,我們可以在 Groovy 中直接撰寫頂層函式,Groovy 會幫我們自動轉為對應的 Java 函式,不需要人為介入。

    函式 (Function) 是什麼

    函式是一種程序抽象化 (procedure abstraction) 的語法特性,其用途在包住一段程式碼,將其使用有意義的名稱包裝起來,之後我們要調用這段程式碼時,就可以直接透過函式名稱呼叫 (call) 該函式,不用重覆撰寫相同的程式碼。函式的虛擬碼如下:

    return-type fn(param_a, param_b, param_c) {
        // Implement some code here.
    }
    

    由此可知,函式有以下要件:

    • 函式名稱
    • 函式的參數 (parameters):零到多個
    • 函式的回傳值 (returning value):零到一個
    • 函式本體,即實作細節

    數學上的函式比較純粹 (pure),都是在進行運算。但電腦程式的函式依其作用分為兩種:

    • 運算 (computing)
    • 狀態 (state) 改變

    第一種函式比較接近數學上的函式,像 Math.sqrt 計算某個數字的平方根;第二種函式則會改變程式的狀態,像是在終端機上印出文字、改變物件的屬性等。撰寫函式的原則是同一個函式儘量不要同時具有兩種作用,將進行運算的函式和狀態改變的函式分開來實作。

    註:在函數式程式設計中,將狀態改變稱為副作用 (side effects)。

    宣告和使用函式

    以下簡例宣告一個函式,並呼叫之:

    // Declare a function.
    void hello() {
        println "Hello World"
    }
    
    // Call the function.
    hello()

    這個函式沒有參數也沒什回傳值,在實務上這類函式用途較少,本例僅用來展示如何建立函式。

    帶有參數或回傳值的函式

    以下簡例建立一個帶有參數和回傳值的函式:

    int add(int a, int b) {
        return a + b
    }
    
    assert add(3, 5) == 8

    大部分函式都會有參數,讓我們調整函式的行為。此外,用來進行運算的函式也會有回傳值。

    設置函式的預設值 (Default Value)

    Groovy 的函式可以加入預設值,如下例:

    String greet(name = "World") {
        "Hello ${name}"
    }
    
    assert greet() == "Hello World"
    assert greet("Michael") == "Hello Michael"

    預設值會在沒有其他值時自動代入。

    遞迴 (Recursion) 函式

    遞迴函式在函式中可呼叫自己,其用意為將問題逐漸縮小。遞迴函式包括兩個要素:

    • 終止條件
    • 遞移步驟

    在練習遞迴函式時,通常是沒有掌握好這兩個要素,造成函式無法收斂。

    費波那西數是一個常見的遞迴程式範例:

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

    要寫好遞迴程式,要有明確的終止條件和遞移步驟。由於遞迴程式在程式設計中時常見且重要的主題,最好還是花一些時間練習。

    【分享本文】
    Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email
    【支持站長】
    Buy me a coffeeBuy me a coffee
    【贊助商連結】
    標籤: GROOVY, JAVA
    【分類瀏覽】