Stories

Detail Return Return

Golang基礎筆記八之函數 - Stories Detail

本文首發於公眾號:Hunter後端

原文鏈接:Golang基礎筆記八之函數

本篇筆記介紹 Golang 裏函數相關的內容,以下是本篇筆記目錄:

  1. 函數的定義語法
  2. 函數返回值
  3. 可變參數函數
  4. 匿名函數
  5. 閉包

1、函數的定義語法

函數的定義格式如下:

func 函數名(參數列表) (返回值列表) { 函數體 }

比如下面是一個兩數相加返回其和的函數:

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

調用的話,直接傳參調用即可:

sum := add(1, 4)
fmt.Println(sum)

傳入的參數可以傳值,也可以傳指針,如果傳指針的話,在函數內部修改後,會影響原值。

以下是一個傳指針修改的示例:

func test(a *int, b int) {
    *a += 2
    b += 2
}
func main() {
    a := 1
    b := 1
    fmt.Printf("調用前 a:%d, b:%d\n", a, b)
    test(&a, b)
    fmt.Printf("調用後 a:%d, b:%d\n", a, b)
}

輸出結果為:

調用前 a:1, b:1
調用後 a:3, b:1

2、函數返回值

函數返回值可以返回單個或多個,在函數定義的時候指定返回類型即可:

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

還可以對返回值命名,就是在定義函數的時候,將返回值提前聲明定義,然後在函數內部對其賦值,函數末尾可以省去 return 具體變量的操作。

比如下面:

func calc(a, b int) (sum, sub int) {
    sum = a + b
    sub = a - b
    return
}

3、可變參數函數

可變參數函數可以接受任意數量的參數,在函數定義的時候,類型前面加上 ... 即表示該參數是可變參數,而在函數內部,可將其作為切片使用。

下面是一個示例,可以接受任意多個元素,作為求和函數的參數:

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

調用的時候,可以直接傳入任意數量參數:

sum(1, 2, 3, 4)

也可以傳入一個切片:

slice := []int{1, 2, 3}
s2 := sum(slice...)

4、匿名函數

匿名函數通常用於臨時需要處理某個功能,或需要將其作為參數傳遞給其他變量的場景。
比如下面定義並立即調用了匿名函數:

total := func(a, b int) int {
    return a + b
}(2, 4)

也可以將其賦值給某個變量,再由該變量來調用:

sumFunc := func(a, b int) int {
    return a + b
}
sumFunc(1, 2)

5、閉包

閉包是指能夠讀取其他函數內部變量的函數,即使該函數已經執行完畢,其作用域內的變量也不會被銷燬。

我們可以使用閉包來捕獲外部函數的局部變量,並將其生命週期延長至閉包本身,比如實現一個計數器:

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

counterFunc := counter()
fmt.Println(counterFunc())
fmt.Println(counterFunc())
fmt.Println(counterFunc())
fmt.Println(counterFunc())

也可以根據外部傳入的參數生成不同的閉包實例,比如實現一個計算器:

func calculate(calculate_type string) func(a, b int) int {
    if calculate_type == "add" {
        return func(a, b int) int {
            return a + b
        }
    } else if calculate_type == "sub" {
        return func(a, b int) int {
            return a - b
        }
    } else {
        return func(a, b int) int { return a + b }
    }
}


addFunc := calculate("add")
fmt.Println(addFunc(10, 5))

subFunc := calculate("sub")
fmt.Println(subFunc(3, 1))

而閉包也可以維護迭代的狀態,因此可以實現迭代器的功能,比如實現一個斐波那契數列生成器:

func fibonacci() func() int {
    a, b := 0, 1
    return func() int {
        f_count := a
        a, b = b, a+b
        return f_count
    }
}

f := fibonacci()
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
user avatar xyjzfx Avatar u_17400586 Avatar u_17353607 Avatar free_like_bird Avatar huaihuaidehongdou Avatar god23bin Avatar meiyoufujideyidongdianyuan Avatar xiaohuzideboluo_cvmeub Avatar kubesphere Avatar ximinghui Avatar ansurfen Avatar winfacter Avatar
Favorites 34 users favorite the story!
Favorites

Add a new Comments

Some HTML is okay.