06.函式

JJJhr發表於2024-07-07

Go 語言中的函式是程式碼組織和複用的基礎,函式的定義和呼叫非常簡單明瞭。下面是 Go 語言中函式的基礎語法和一些關鍵概念:

函式的定義

在 Go 語言中,函式的定義包括函式名、引數列表、返回值型別和函式體。語法格式如下:

func 函式名(引數列表) 返回值型別 {
    函式體
}

示例

下面是一個簡單的函式示例,該函式接收兩個整數引數並返回它們的和:

package main

import "fmt"

// 定義一個函式 add,接收兩個整數引數 a 和 b,返回它們的和
func add(a int, b int) int {
    return a + b
}

func main() {
    // 呼叫 add 函式,並將返回值賦給 sum
    sum := add(3, 4)
    fmt.Println("3 + 4 =", sum) // 輸出:3 + 4 = 7
}

引數和返回值

  • 多個引數:如果引數列表中有多個引數,它們之間用逗號分隔。如果多個引數的型別相同,可以省略重複的型別宣告:

    func add(a, b int) int {
        return a + b
    }

  • 多個返回值:Go 語言支援函式返回多個值:

    func swap(x, y string) (string, string) {
        return y, x
    }
    
    func main() {
        a, b := swap("hello", "world")
        fmt.Println(a, b) // 輸出:world hello
    }

命名返回值

函式的返回值可以命名,這樣可以在函式體中直接使用這些變數,並在函式末尾使用 return 語句返回:

func split(sum int) (x, y int) {
    x = sum * 4 / 9
    y = sum - x
    return
}

func main() {
    a, b := split(17)
    fmt.Println(a, b) // 輸出:7 10
}

空白識別符號 _

如果函式返回多個值,但你不需要使用其中的某些值,可以使用空白識別符號 _ 忽略它們:

func foo() (int, int, int) {
    return 1, 2, 3
}

func main() {
    a, _, c := foo()
    fmt.Println(a, c) // 輸出:1 3
}

可變引數

Go 語言支援可變引數函式,即函式引數的個數可以是可變的。語法是使用省略號 ... 表示可變引數:

func sum(numbers ...int) int {
    total := 0
    for _, number := range numbers {
        total += number
    }
    return total
}

func main() {
    fmt.Println(sum(1, 2, 3))    // 輸出:6
    fmt.Println(sum(1, 2, 3, 4)) // 輸出:10
}

小結

  • 函式是 Go 語言中程式碼複用的基本單位。
  • 函式可以有多個引數和返回值。
  • 函式引數和返回值可以命名,增加程式碼的可讀性。
  • 可變引數函式可以接收任意數量的引數。

透過理解這些基本語法,可以在 Go 語言中更有效地定義和使用函式。

課程案例

實現加減乘除

package main

import "fmt"

func eval(a, b int, op string) int {
    switch op {
    case "+":
        return a + b
    case "-":
        return a - b
    case "*":
        return a * b
    case "/":
        return a / b
    default:
        panic("unsupported operation" + op)
    }
}
func main() {
    fmt.Println(eval(1, 2, "+"))
}

執行結果:

取餘操作

func div(a, b int) (int, int) {
    return a / b, a % b
}
func main() {
    fmt.Println(div(10, 2))
    fmt.Println(div(10, 3))
}

寫法二:

package main

import "fmt"

func div(a, b int) (quotient, remainder int) {
    return a / b, a % b
}
func main() {
    quotient, remainder := div(10, 3)
    fmt.Println(quotient, remainder)
}

兩個返回值只想要一個的情況:

    case "/":
        quotient, _ := div(a, b)
        return quotient

處理非法制報錯操作

package main

import "fmt"

func eval(a, b int, op string) (int, error) {
    switch op {
    case "+":
        return a + b, nil
    case "-":
        return a - b, nil
    case "*":
        return a * b, nil
    case "/":
        quotient, _ := div(a, b)
        return quotient, nil
    default:
        //會中斷執行
        //panic("unsupported operation" + op)
        return 0, fmt.Errorf("unsupported operation: %s", op)
    }
}
func div(a, b int) (quotient, remainder int) {
    return a / b, a % b
}
func main() {
  if result, err := eval(1, 2, "x"); err != nil {
  fmt.Println("Error:", err)
  } else {
    fmt.Println(result)
  }
}

執行結果:

nil 是一個預定義的識別符號,表示函式呼叫成功且沒有錯誤發生。具體來說,nilerror 型別的零值,表示沒有錯誤。讓我們詳細解釋一下 nil 在你的程式碼中的作用。

nileval 函式中的作用

定義了一個名為 eval 的函式,這個函式接受兩個整數 ab 以及一個字串 op(表示運算子),然後根據運算子執行相應的算術運算。函式返回一個整數結果和一個 error 型別的值。

在這個函式中:

  1. return a + b, nil 等等:

    • 當運算子是 "+""-""*""/" 時,函式返回計算結果和 nil。這裡的 nil 表示沒有錯誤發生。例如,return a + b, nil 意味著加法操作成功,沒有錯誤。
  2. return 0, fmt.Errorf("unsupported operation: %s", op):

    • 如果運算子不在支援的範圍內(即既不是 "+""-""*" 也不是 "/"),函式返回 0 和一個 error 型別的值,表示發生了不支援的操作錯誤。fmt.Errorf 建立一個帶有格式化字串的 error 物件。

nil 的意義

在 Go 語言中,函式通常使用返回值 error 來表示函式是否成功執行。如果 error 返回 nil,則表示函式成功執行,沒有發生錯誤。如果 error 返回非 nil 的值,則表示函式執行過程中發生了錯誤。透過這種方式,Go 語言避免了使用異常處理錯誤。

運算方法重寫案例

package main

import (
    "fmt"
    "math"
    "reflect"
    "runtime"
)


func apply(op func(int, int) int, a, b int) int {
    p := reflect.ValueOf(op).Pointer()
    opName := runtime.FuncForPC(p).Name()
    fmt.Printf("Calling function %s with arguments"+"(%d, %d)\n", opName, a, b)
    return op(a, b)
}
func pow(a, b int) int {
    return int(math.Pow(float64(a), float64(b)))
}

func main() {
    fmt.Println(apply(pow, 3, 4))
}

相關文章