defer 介紹

Deferred nil func

如果 defer 指到 nil 函數,則會出現panic錯誤。

func() {
  var run func() = nil
  defer run()
  fmt.Println("runs")
}

輸出:

runs
panic: runtime error: invalid memory address or nil pointer dereference

Defer inside a loop

defer inside a looop
這種用法下,defer row.Close() 會在函數結束後才被執行,會造成不可預期的錯誤。
* 解法一:直接結束

func() {
   for {
      row, err := db.Query("select ...")
      if err != nil {
         ...
      }
      row.Close()
   }
}
  • 解法二:呼叫另一個函數

func() { for { func() { row, err := db.Query("select ...") if err != nil { ... } row.Close() }() } }

基本上使用defer會比沒有使用執行速度快很多很多。所以建議大家使用defer。

Defer as a wrapper

func() {
  db := &database{}
  close := db.connect()
  defer close()

  fmt.Println("query db...")
}
  • 輸出
connect
query db...
disconnect