Go 語言中的閉包
本文主要介紹 Go 語言中的閉包。簡單的說 Go 語言的閉包就是一個(gè)引用了外部自由變量的匿名函數(shù),被引用的自由變量和該匿名函數(shù)共同存在,不會因?yàn)殡x開了外部環(huán)境就被釋放或者刪除,還可以在這個(gè)匿名函數(shù)中繼續(xù)使用。
1. Go 語言的匿名函數(shù)
在上文中我們了解到了一個(gè)新的詞匯——匿名函數(shù),我們先來學(xué)習(xí)一下Go語言中的匿名函數(shù),再來了解在 Go 語言中如何使用閉包。匿名函數(shù),顧名思義,就是隱藏函數(shù)名的函數(shù)。
代碼示例:
- 1?
package main
- 2
- 3?
import (
- 4? ? ? ? ?
"fmt"
- 5?
)
- 6
- 7?
var f = func() {
- 8? ? ? ? ?
fmt.Println("匿名函數(shù)作為變量來使用")
- 9?
}
- 10
- 11?
func main() {
- 12? ? ? ? ?
f()
- 13
- 14? ? ? ? ??
func(){
- 15? ? ? ? ? ? ? ? ?
fmt.Println("匿名函數(shù)直接使用")
- 16? ? ? ? ?
}()
- 17?
}
- 第7~9行:定義一個(gè)函數(shù)類型,值為一個(gè)匿名函數(shù)的變量;
- 第 12 行:使用這個(gè)匿名函數(shù);
- 第 14~16 行:定義一個(gè)匿名函數(shù)。在這個(gè)函數(shù)后加上
()
,就可以直接使用這個(gè)匿名函數(shù)。
執(zhí)行結(jié)果:

2. 匿名函數(shù)引用外部變量
如果在匿名函數(shù)內(nèi),使用了外部環(huán)境的變量,就構(gòu)成了一個(gè)閉包。簡單來講就是一個(gè)函數(shù)內(nèi),使用匿名函數(shù)來操作函數(shù)內(nèi)聲明的變量。
代碼示例:
- 1?
package main
- 2
- 3?
import (
- 4? ? ? ? ?
"fmt"
- 5?
)
- 6
- 7?
func main() {
- 8? ? ? ? ?
str := "Hello World!"
- 9? ? ? ? ?
func() {
- 10? ? ? ? ? ? ? ?
str = "Hello Codey!"
- 11? ? ? ?
}()
- 12? ? ? ?
fmt.Println(str)
- 13?
}
- 第 10 行:匿名函數(shù)直接操作了main函數(shù)之中的變量str,將其修改為了"Hello Codey!";
- 第 12 行:輸出變量的值。
執(zhí)行結(jié)果:

上述例子簡單的構(gòu)造了一個(gè)閉包,在匿名函數(shù)中并沒有聲明或者定義str這個(gè)變量,但是可以直接操作,就是引用可main函數(shù)中的自由變量。這個(gè)例子可能對自由變量的引用表現(xiàn)不是很直觀,我們接下來使用defer和閉包相結(jié)合,深入了解一下閉包中的引用外部變量。
代碼示例:
- 1?
package main
- 2
- 3?
import (
- 4? ? ? ? ?
"fmt"
- 5?
)
- 6
- 7?
func main() {
- 8? ? ? ? ?
str := "Hello World!"
- 9? ? ? ? ?
defer func() {
- 10? ? ? ? ? ? ? ?
fmt.Println("defer str=", str)
- 11? ? ? ?
}
()
- 12? ? ? ?
str = "Hello Codey!"
- 13? ? ? ?
fmt.Println("main str=", str)
- 14?
}
執(zhí)行結(jié)果:

從執(zhí)行結(jié)果上來看應(yīng)該是蠻出人意料的,因?yàn)榍拔慕榻B defer 的時(shí)候明確介紹了 defer 后變量是保留它在 defer 時(shí)的值,而不會被 defer 之后的代碼所改變。但是在閉包這邊這個(gè)看起來不太適用,其實(shí)是適用的,只是閉包是引用了這個(gè)變量,也就是說,在 defer 時(shí)被保留下來的是這個(gè)變量的地址,后續(xù)代碼改變的不是地址,而是這個(gè)地址存儲的值,所以后續(xù)代碼對這個(gè)變量的操作,都會反應(yīng)到這個(gè) defer 中。
Tips:關(guān)于變量的地址,在后續(xù)的Go語言的指針中會有詳細(xì)的介紹。
3. 小結(jié)
本文主要介紹了 Go 語言中閉包的使用,需要注意以下幾點(diǎn):
- 閉包就是匿名函數(shù)引用外部變量
- 閉包中引用的變量會被外部環(huán)境改變,同時(shí)閉包內(nèi)對變量的改變也會影響到外部環(huán)境的使
文章來源于網(wǎng)絡(luò),侵刪!