1. 程式人生 > 其它 >匿名函式和閉包

匿名函式和閉包

Go語言基礎之匿名函式和閉包

一、匿名函式

函式還可以作為返回值,但是在Go語言中函式內部不能再像之前那樣定義函數了,只能定義匿名函式。匿名函式就是沒有函式名的函式,匿名函式的定義格式如下:

func(引數)(返回值){
    函式體
}

匿名函式因為沒有函式名,所以沒辦法像普通函式那樣呼叫,所以匿名函式需要儲存到某個變數或者作為立即執行函式:

func main() {
    // 將匿名函式儲存到變數
    add := func(x, y int) {
        fmt.Println(x + y)
    }
    add(10, 20) // 通過變數呼叫匿名函式

    //自執行函式:匿名函式定義完加()直接執行
    func(x, y int) {
        fmt.Println(x + y)
    }(10, 20)
}

匿名函式多用於實現回撥函式和閉包。

二、閉包

閉包指的是一個函式和與其相關的引用環境組合而成的實體。簡單來說,閉包=函式+引用環境。 首先我們來看一個

閉:指的是定義在函式內部的函式,注意,在Go語言中,定義在函式內部的函式必須是匿名函式

包:閉函式包含了對外層函式名字的引用

例子:

func adder() func(int) int {
    var x int
    return func(y int) int {
        x += y
        return x
    }
}
func main() {
    var f = adder()  // f = func(y int) int{...}
    fmt.Println(f(10)) //10
    fmt.Println(f(20)) //30
    fmt.Println(f(30)) //60

    f1 := adder()
    fmt.Println(f1(40)) //40
    fmt.Println(f1(50)) //90
}

變數f是一個函式並且它引用了其外部作用域中的x變數,此時f就是一個閉包。 在f的生命週期內,變數x也一直有效。 閉包進階示例1:

func adder2(x int) func(int) int {
    return func(y int) int {
        x += y
        return x
    }
}
func main() {
    var f = adder2(10)
    fmt.Println(f(10)) //20
    fmt.Println(f(20)) //40
    fmt.Println(f(30)) //70

    f1 := adder2(20)
    fmt.Println(f1(40)) //60
    fmt.Println(f1(50)) //110
}

閉包進階示例2:

func makeSuffixFunc(suffix string) func(string) string {
    return func(name string) string {
        if !strings.HasSuffix(name, suffix) {
            return name + suffix
        }
        return name
    }
}

func main() {
    jpgFunc := makeSuffixFunc(".jpg")
    txtFunc := makeSuffixFunc(".txt")
    fmt.Println(jpgFunc("test")) //test.jpg
    fmt.Println(txtFunc("test")) //test.txt
}

閉包進階示例3:

func calc(base int) (func(int) int, func(int) int) {
    add := func(i int) int {
        base += i
        return base
    }

    sub := func(i int) int {
        base -= i
        return base
    }
    return add, sub
}

func main() {
    f1, f2 := calc(10)
    fmt.Println(f1(1), f2(2)) //11 9
    fmt.Println(f1(3), f2(4)) //12 8
    fmt.Println(f1(5), f2(6)) //13 7
}

閉包其實並不複雜,只要牢記閉包=函式+引用環境

三、總結

  1. 匿名函式,匿名函式因為沒有函式名,所以沒辦法像普通函式那樣呼叫,匿名函式需要儲存到某個變數或者作為立即執行函式

    func(引數)(返回值){
        函式體
    }
    
  2. 閉包:閉包指的是一個函式和與其相關的引用環境組合而成的實體。簡單來說,閉包=函式+引用環境

在當下的階段,必將由程式設計師來主導,甚至比以往更甚。