1、GO語言的匿名函數就是閉包
基本概念
閉包是可以包含自由(未綁定到特定對象)變量的代碼塊,這些變量不在這個代碼塊內或者任何全局上下文中定義,而是在定義代碼塊的環境中定義。要執行的代碼塊(由於自由變量包含
在代碼塊中,所以這些自由變量以及它們引用的對象沒有被釋放)為自由變量提供綁定的計算環境(作用域)。
閉包的價值
閉包的價值在於可以作為函數對象或者匿名函數,對於類型系統而言,這意味着不僅要表示數據還要表示代碼。支持閉包的多數語言都將函數作為第一級對象,就是說這些函數可以存儲到
變量中作為參數傳遞給其他函數,最重要的是能夠被函數動態創建和返回。
Go語言中的閉包
Go語言中的閉包同樣也會引用到函數外的變量。閉包的實現確保只要閉包還被使用,那么被閉包引用的變量會一直存在。例:
// closure.go package main import ( "fmt" ) func main() { var j int = 5 a := func() func() { var i int = 10 return func() { fmt.Printf("i, j: %d, %d\n", i, j) } }() //末尾的括號表明匿名函數被調用,並將返回的函數指針賦給變量a a() j *= 2 a() }
輸出:
i, j: 10, 5
i, j: 10, 10
2、Go語言支持匿名函數,即函數可以像普通變量一樣被傳遞或使用。
閉包是“函數”和“引用環境”組成的整體。
func anonymous(n int) func() {
return func() {
n++ //對外部變量加1
fmt.Println(n)
}
}
func anonymous2(n int) func() {
sum := n
a := func() { //把匿名函數作為值賦給變量a(Go不允許函數嵌套,但你可以利用匿名函數實現函數嵌套)
fmt.Println(sum + 1) //調用本函數外的變量,這里沒有()匿名函數不會馬上執行
}
return a
}
fmt.Println("---------anonymous func--------")
anony := anonymous(10)
anony()
anony1 := anonymous(20)
anony1()
/**
*再次調用anony()函數,結果是12,由此得出以下兩點
* 1、內函數對外函數的變量的修改,是對變量的引用
* 2、變量被引用后,它所在的函數結束,該變量不會馬上銷毀
**/
anony()
anony1()
fmt.Println("---------anonymous2----------")
an := anonymous2(10)
an()
an2 := anonymous2(20)
an2()
an()
an2()
輸出:
---------anonymous func-------- 11 21 12 22 ---------anonymous2---------- 11 21 11 21
對象是附有行為的數據,而閉包是附有數據的行為。
3、匿名函數執行
匿名函數最后括號中加參數,匿名函數立即執行,沒有括號或括號中為空,則需要傳參。例:
fmt.Println("-----------匿名函數的執行----------") m, n := func(i, j int) (m, n int) { // x y 為函數返回值 return j, i }(1, 9) // 直接創建匿名函數並執行 fmt.Println(m, n) f := func(i, j int) (result int) { // f 為函數地址 result = i + j return result } fmt.Println(f(1, 2))
輸出:
-----------匿名函數的執行---------- 9 1 3
4、錯誤: expression in go/defer must be function call
go關鍵字后跟匿名函數報錯: expression in go/defer must be function call,在匿名函數后加括號則可。例:
func smtp() error { return nil }
go func() { err := smtp() if err != nil { fmt.Printf(err.Error()) } }()
若去掉上面代碼中的空括號會報錯。
加()封裝成表達式。
參考資料:
1、http://blog.sina.com.cn/s/blog_487109d101018fcx.html
2、http://www.golangtc.com/t/5325047a320b523f0a00008b
3、《GO語言編程》
4、http://www.cnblogs.com/ruixiazhixia/p/6024758.html