1. 程式人生 > >【Go】defer踩坑指南

【Go】defer踩坑指南

我們在Go專案中,經常使用defer來完成日誌管理、打點等輔助功能,非常nice,但是有個坑需要注意:

1、關於閉包:

defer方法原理是編譯時先將defer內容堆疊,然後在方法return之前,彈棧並依次執行。因此defer閉包和顯示呼叫會有引數差異。

例如:

func Test(t *testing.T) {
  i := 1
  defer logs.Error("i=%d", i)
  i = 2
  return
}

這裡defer在編譯時,直接將logs.Error("i=%d", 1)堆進棧,然後在return前執行,結果是"i=1"

而:

func Test(t *testing.T) {
  i := 1
  defer func() {
    logs.Error("i=%d", i)
  }()  
  i = 2
  return
}

這裡defer編譯時只將閉包func扔進棧,所以在return前再呼叫時,臨時拿到外部方法的引數最終值i=2,因此結果是"i=2"。

失了個智