Go語言之defer
阿新 • • 發佈:2018-12-23
defer關鍵字
defer和go一樣都是Go語言提供的關鍵字. defer用於資源的釋放, 會在函式返回之前進行呼叫. 要使用好defer最重要的是要理解return執行過程: 先給返回值賦值, 然後呼叫defer表示式, 最後才是返回到呼叫函式中. 理解了這句話, 關於defer的疑惑都能迎刃而解了.
例子
例一:
func f1() (result int) {
defer func() {
result++
}()
return 0
}
return時先將對result賦值0, 然後defer中對result++, 此時result=1; 最後返回時result=1,即呼叫函式獲得值2.
例二:
func f2() (r int) {
t := 5
defer func() {
t = t + 5
}()
return t
}
return時先將t的值5賦值給r(值傳遞); 然後defer中對加5,此時t=10,r=5; 最後返回時r=5, 即呼叫函式獲得值5.
例三:
func f3() (r int) {
defer func(r int) {
r = r + 5
}(r)
return 1
}
return時先將1賦值給r; 然後呼叫defer時將r的值傳遞給defer函式, 注意defer函式中的r已經與函式f3返回的r不是一個變數(值傳遞), 因此r的修改不會影響f3返回值; 最後返回時r=1, 即呼叫函式獲得值1.
例四:
func addCounter() {
for count := 0; count < 2; count++ {
defer lock.Unlock()
//do someThing
lock.Lock()
}
}
將解鎖放到defer中是為了防止執行任務(do someThing)時panic導致程式異常結束而未解鎖。實際執行時該例子會產生死鎖, 原因是(1) Muxtex不是可重入鎖; (2) defer會在函式結束時執行,而不是在每一輪for迴圈結束時執行。正確寫法如下:
func addCounter() { for count := 0; count < 2; count++ { doSomeThing() } } func doSomeThing() { lock.Lock() defer lock.Unlock() //do someThing }