匿名函式和閉包
阿新 • • 發佈:2021-10-16
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
}
閉包其實並不複雜,只要牢記閉包=函式+引用環境
。
三、總結
-
匿名函式,匿名函式因為沒有函式名,所以沒辦法像普通函式那樣呼叫,匿名函式需要儲存到某個變數或者作為立即執行函式
func(引數)(返回值){ 函式體 }
-
閉包:閉包指的是一個函式和與其相關的引用環境組合而成的實體。簡單來說,
閉包=函式+引用環境