函式

Go 語言函式:閉包、高階函式、遞迴。

Closures

閉包是可以捕獲並存取其外部作用域變數的匿名函式。

func counter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

func main() {
    c := counter()
    fmt.Println(c()) // 1
    fmt.Println(c()) // 2
    fmt.Println(c()) // 3
}

High Order Function

高階函式:接受函式作為參數或回傳函式。

// 接受函式作為參數
func apply(nums []int, fn func(int) int) []int {
    result := make([]int, len(nums))
    for i, v := range nums {
        result[i] = fn(v)
    }
    return result
}

// 使用
double := func(n int) int { return n * 2 }
nums := []int{1, 2, 3, 4}
doubled := apply(nums, double) // [2, 4, 6, 8]

Filter 範例

func filter(nums []int, fn func(int) bool) []int {
    var result []int
    for _, v := range nums {
        if fn(v) {
            result = append(result, v)
        }
    }
    return result
}

// 使用
isEven := func(n int) bool { return n%2 == 0 }
evens := filter([]int{1, 2, 3, 4, 5, 6}, isEven) // [2, 4, 6]

Reduce 範例

func reduce(nums []int, fn func(int, int) int, initial int) int {
    result := initial
    for _, v := range nums {
        result = fn(result, v)
    }
    return result
}

// 使用
sum := reduce([]int{1, 2, 3, 4}, func(a, b int) int { return a + b }, 0) // 10

Recursion

遞迴函式,閉包也可以是遞迴的。

// 階乘
func factorial(n int) int {
    if n <= 1 {
        return 1
    }
    return n * factorial(n-1)
}

// 費氏數列
func fibonacci(n int) int {
    if n <= 1 {
        return n
    }
    return fibonacci(n-1) + fibonacci(n-2)
}

閉包遞迴

var fib func(n int) int
fib = func(n int) int {
    if n <= 1 {
        return n
    }
    return fib(n-1) + fib(n-2)
}

Methods

方法是附加在型別上的函式。

Receiver Type

類型特性使用時機
Value Receiver複製值,不影響原值讀取操作、小型 struct
Pointer Receiver操作原記憶體位址修改操作、大型 struct
type Rectangle struct {
    Width, Height float64
}

// Value Receiver - 不會修改原值
func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}

// Pointer Receiver - 可以修改原值
func (r *Rectangle) Scale(factor float64) {
    r.Width *= factor
    r.Height *= factor
}

func main() {
    rect := Rectangle{10, 5}
    fmt.Println(rect.Area()) // 50

    rect.Scale(2)
    fmt.Println(rect.Area()) // 200
}

Defer

延遲執行,以 LIFO(後進先出)順序執行,常用於資源清理。

func readFile(filename string) error {
    f, err := os.Open(filename)
    if err != nil {
        return err
    }
    defer f.Close() // 函式結束時自動關閉

    // 讀取檔案...
    return nil
}

多個 Defer

func main() {
    defer fmt.Println("1")
    defer fmt.Println("2")
    defer fmt.Println("3")
    // 輸出順序: 3, 2, 1 (LIFO)
}

Defer 與錯誤處理

func doSomething() (err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("recovered: %v", r)
        }
    }()

    // 可能 panic 的操作...
    return nil
}

Variadic Functions

可變參數函式,接受任意數量的參數。

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

func main() {
    fmt.Println(sum(1, 2))          // 3
    fmt.Println(sum(1, 2, 3, 4, 5)) // 15

    // 展開 slice
    nums := []int{1, 2, 3}
    fmt.Println(sum(nums...)) // 6
}

Sorting

使用 sort 套件進行排序。

import "sort"

// 基本排序
nums := []int{3, 1, 4, 1, 5, 9}
sort.Ints(nums) // [1, 1, 3, 4, 5, 9]

strs := []string{"banana", "apple", "cherry"}
sort.Strings(strs) // ["apple", "banana", "cherry"]

自訂排序

type Person struct {
    Name string
    Age  int
}

people := []Person{
    {"Alice", 30},
    {"Bob", 25},
    {"Charlie", 35},
}

// 依年齡排序
sort.Slice(people, func(i, j int) bool {
    return people[i].Age < people[j].Age
})

實作 sort.Interface

type ByAge []Person

func (a ByAge) Len() int           { return len(a) }
func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }

sort.Sort(ByAge(people))

相關主題