Golang | 匿名函式和閉包
阿新 • • 發佈:2022-01-25
匿名函式
匿名函式就是一個沒有名字的函式,當我們在一個函式內部重複呼叫一段程式碼, 並且這段程式碼不想被別的函式使用,我們就可以定義一個匿名函式,或者在一段程式碼需要併發的時候使用匿名函式。
例如:
func main() { f := func() { fmt.Println("hello,world!") } // 第一次呼叫 f() // 第二次呼叫 f() // 第三次呼叫 f() // 加鎖 wg := sync.WaitGroup{} wg.Add(100) // 併發列印一句話,100次 for i := 0; i < 100; i++ { go func(i int) { fmt.Printf("迴圈第%d次\n",i) // 標記每一個協程的結束 wg.Done() }(i+1) } // 等待所有協程都執行完畢才會結束程式 wg.Wait() }
上面就是匿名函式的兩個應用場景
閉包
閉包就是也是匿名函式的一種,它們允許呼叫定義在其它環境下的變數,閉包可以使當前函式捕捉到一個外部狀態,一個閉包繼承了函式所宣告時的作用域,因此,作用域內的所有變數都被共享到了當前函式內,我們可以直接操作這個變數。閉包返回的時候,並不是單純的返回一個函式,返回的是一個結構體,其中記錄了函式返回地址和引用的環境中的變數地址。
一個簡單的例子:
func AddInt() func(i int) int{ var num int return func(i int) int { num += i return num } } func main() { fn := AddInt() fmt.Println(fn(1)) // 1 fmt.Println(fn(1)) // 2 fmt.Println(fn(1)) // 3 fmt.Println(fn(1)) // 4 }
以上的小例子中,我們每一次呼叫fn 函式,每一次只在 addInt 中做加法,按照我們的理解應該l輸出的全都是 1 ,但是現在輸出的卻是幾次呼叫的和,這就說明了,在呼叫閉包函式的時候,當前函式可以閉包中的變數,也可以說明,閉包函式返回的 fn中,包含著函式的地址和當前環境中使用的變數地址。
看一下其它的閉包應用:
// 斐波那契數列: func fibonacci() func() int { a, b := 0, 1 return func() int { a , b = b , a + b return a } } func main() { f := fibonacci() for i := 0; i < 10; i++ { fmt.Println(f()) } // 輸出: // 1 // 1 // 2 // 3 // 5 // 8 // 13 // 21 // 34 // 55 }
// 裝飾器 & 中間函式
func wrapping(f func() string) {
fmt.Println("do my work...")
fmt.Println("wrapping function: ", f())
fmt.Println("my work finished !")
}
func sayHello() string {
return "Hello !"
}
func sayByeBye() string {
return "Bye Bye !"
}
func main() {
wrapping(sayHello)
wrapping(sayByeBye)
}
/*
輸出:
do my work...
wrapping function: Hello !
my work finished !
do my work...
wrapping function: Bye Bye !
my work finished !
*/
關注公眾號,隨時獲取最新資訊
細節決定成敗!
個人愚見,如有不對,懇請斧正!