Golang學習筆記之延遲函式(defer)
關鍵字 defer ⽤於註冊延遲調⽤。這些調⽤直到 ret 前才被執⾏,通常⽤於釋放資源或錯誤處理。
一、當defer被宣告時,其引數就會被實時解析
func a() { i := 0 defer fmt.Println(i) //輸出0,因為i此時就是0 i++ defer fmt.Println(i) //輸出1,因為i此時就是1 return }
二、當一個函式內多次呼叫 defer 時,Go 會把 defer 呼叫放入到一個棧中,隨後按照先進後出的順序執行。
func main() { defer fmt.Println("1") defer fmt.Println("2") defer fmt.Println("3") defer fmt.Println("4") }
輸出順序為4321
使用defer逆序輸出字串
name := "Naveen你好" fmt.Printf("%s\n", string(name)) fmt.Printf("逆序:") defer fmt.Printf("\n") for _, v := range []rune(name) { defer fmt.Printf("%c", v) }
輸出:
Naveen你好
逆序:好你neevaN
三、defer 的實際應用
func (r rect) area(wg *sync.WaitGroup) { if r.length < 0 { fmt.Printf("rect %v's length should be greater than zero\n", r) wg.Done() return } if r.width < 0 { fmt.Printf("rect %v's width should be greater than zero\n", r) wg.Done() return } area := r.length * r.width fmt.Printf("rect %v's area %d\n", r, area) wg.Done() }
我們會發現上面wg.Done()被呼叫多次我們可以使用defer來優化程式碼
func (r rect) area(wg *sync.WaitGroup) { defer wg.Done() if r.length < 0 { fmt.Printf("rect %v's length should be greater than zero\n", r) return } if r.width < 0 { fmt.Printf("rect %v's width should be greater than zero\n", r) return } area := r.length * r.width fmt.Printf("rect %v's area %d\n", r, area) }
使用defer延時呼叫,會在程式結束之前呼叫