Go語言中defer的使用

defer是個Go語言中的一個關鍵詞。從語法上來講,defer語句是defer關鍵詞後面跟着一個函數/方法調用。函數和參數表達式在defer語句所在的位置就已經被檢驗了。但是實際上的函數/方法調用的話,一直推遲到所在函數的返回結束或者出錯結束。任何調用都可以被推遲。多個被推遲的函數調用,實際調用順序正好與它們代碼調用位置相反。


func print(a int) {
    fmt.Println(a)
}

func Add(a, b int) int {
    defer print(a)
    
    a = a + b
    
    return a
}

fmt.Println(Add(4, 3))

上面這段代碼,defer語句輸出的是4,Add返回的值是7。


defer可以用於文件的打開和關閉,鎖的打開和關閉。

package ioutil

func ReadFile(filename string) ([]byte, error) {
    f, err := os.Open(filename)
    if err != nil {
        return nil, err
    }
    defer f.close()
    return ReadAll()
}

上面的代碼在執行完return語句後,文件指針f被關閉。


var mu sync.Mutex
var m = make(map[string]int)

func lookup(key string) int {
    mu.Lock()
    defer mu.Unlock()
    return m[key]
}

上面代碼先上鎖,進入臨界區,返回m裏key對應的值,然後退出臨界區,解除鎖。


如果函數的返回值有變量名,defer可以用於打印函數返回值。這在debug中有一定用處。

func double(x int) (result int) {
    defer func() { fmt.Println("double(%d) = %d\n", x, result) }()
    return x + x
}

_ = double(4)

上面的函數會輸出“double(4) = 8"。

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