下面由golang教學專欄來介紹golang中的閉包的意義和用法,希望對需要的朋友有幫助!
#什麼是閉包?
Go 函數可以是一個閉包。閉包是一個函數值,它引用了函數體之外的變數。這個函數可以對這個引用的變數進行存取和賦值;換句話說這個函數被「綁定」在這個變數上。
我的不可靠的理解,一個閉包相當於一個類別的實例,函數體之外的變數相當於這個實例儲存的變數。
沒有閉包的時候,函數就是一次性買賣,函數執行完畢後就無法再更改函數中變數的值(應該是記憶體釋放了);有了閉包後函數就變成了一個變數的值,只要變數沒被釋放,函數就會一直處於存活並獨享的狀態,因此可以後期更改函數中變數的值(因為這樣就不會被go給回收記憶體了,會一直快取在那裡)。
閉包的主要意義
縮小變數作用域,減少對全域變數的污染。下面的累加如果用全域變數進行實現,全域變數容易被其他人污染。同時,所有我要實作n個累加器,那麼每次都需要n個全域變數。利用背包,每個產生的累加器myAdder1, myAdder2 := adder(), adder()
有自己獨立的sum,sum可以看作為myAdder1.sum與myAdder2.sum。
利用背包可以實現有自己狀態的函數!
package mainimport ( "fmt")func adder() func(int) int { sum := 0 return func(x int) int { sum += x return sum }}func main() { myAdder := adder() // 从1加到10 for i := 1; i <= 10; i++ { myAdder(i) } fmt.Println(myAdder(0)) // 再加上45 fmt.Println(myAdder(45))}
結果:
55 // 1+...+10 100
範例
#利用閉包實作斐波拉契數列
package mainimport ( "fmt")func fibonacci() func() int { b0 := 0 b1 := 1 return func() int { tmp := b0 + b1 b0 = b1 b1 = tmp return b1 }}func main() { myFibonacci := fibonacci() for i := 1; i <= 5; i++ { fmt.Println(myFibonacci()) }}
結果:
1 2 3 5 8
易錯點
func B() []func() { b := make([]func(), 3, 3) for i := 0; i < 3; i++ { b[i] = func() { fmt.Println(i) } } return b}func main() { c := B() c[0]() c[1]() c[2]()}
結果:
// 因为都引用i,i最后变成了3 3 3 3
修正方法1:
package mainimport ( "fmt")func B() []func() { b := make([]func(), 3, 3) for i := 0; i < 3; i++ { j := i b[i] = func() { fmt.Println(j) } } return b}func main() { c := B() c[0]() c[1]() c[2]()}
改正方法2:
package mainimport ( "fmt")func B() []func() { b := make([]func(), 3, 3) for i := 0; i < 3; i++ { b[i] = func(j int) func(){ return func() { fmt.Println(j) } }(i) } return b}func main() { c := B() c[0]() c[1]() c[2]()}
更多相關技術文章,請造訪go語言教學欄位!
#以上是你知道golang中的閉包的意義和用法嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!