defer在golang中很多地方進行使用,多數爲文件輸入輸出,
同時,defer是棧的類型,LIFO last in first out, 後進先出模型。defer會在當前函數執行完畢後進行執行
如下方代碼:
func d1() {
for i := 3; i > 0; i-- {
defer fmt.Print(i, " ")
}
}
func d2() {
for i := 3; i > 0; i-- {
defer func() {
fmt.Print(i, " ")
}()
}
}
func d3(){
for i := 3; i > 0; i-- {
defer func(n int) {
fmt.Print(n, " ")
}(i)
}
}
func main() {
d1()
fmt.Println()
d2()
fmt.Println()
d3()
}
d1, d2, d3分別打印:
1 2 3
0 0 0
1 2 3
我們發現,d2中,defer採用匿名函數,打印的是0 0 0, 這是因爲defer是在函數所有代碼執行完畢後執行,此時i已經自減到0了, defer匿名函數中使用的i變量與for循環i爲同一內存。
d1在直接使用defer時 後面跟進函數,這個時候i進行了拷貝,並不與for中i共享內存
d3爲定義匿名函數,同時傳入參數值
推薦使用d3方法,保證每次將i進行拷貝把函數放入棧中