golang defer tricky

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進行拷貝把函數放入棧中

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章