Golang-defer關鍵字 defer關鍵字

defer關鍵字

defer是Golang中一個非常重要的關鍵字,主要是用於註冊延遲調用,這些調用在return時纔會執行,通常用來銷燬資源

示例

簡單場景

最簡單的使用場景

import "fmt"

type handler struct {

}

func (h *handler) close() {
    fmt.Println("close handler")
}
func (h *handler) call() {
    fmt.Println("call function exec")
}

func  main() {
    h := new(handler)
    defer h.close()

    h.call()
}
call function exec
close handler

defer註冊的函數是在return返回時纔會被調用,主要用於關閉一些資源句柄之類的

多次註冊

註冊多個調用的場景

package main

import "fmt"

type handler struct {

}

func (h *handler) close1() {
    fmt.Println("close1 handler")
}

func (h *handler) close2() {
    fmt.Println("close2 handler")
}

func (h *handler) call() {
    fmt.Println("call function exec")
}

func  main() {
    h := new(handler)
    defer h.close1()
    defer h.close2()

    h.call()
}
call function exec
close2 handler
close1 handler

defer允許註冊多個調用,按先進後出的順序執行

變量修改

在註冊後修改了變量所指向的值的情況

package main

import "fmt"

type handler struct {
    i   int
}

func (h *handler) close() {
    fmt.Println(h.i, "close handler")
}

func  main() {
    h := &handler{i: 1}
    defer h.close()

    h = &handler{i: 2}
}
1 close handler

defer所註冊的函數參數會被複制一份保存起來,並不受後續的修改所影響
不過要注意的是這裏只是複製了go的指針,指針指向的地址不會變,但是指針指向的地址上的內容是可以修改變動的

閉包

與上面一種場景相似的就是閉包的場景

package main

import "fmt"

type handler struct {
    i   int
}

func (h *handler) close() {
    fmt.Println(h.i, "close handler")
}

func  main() {
    h := &handler{i: 1}
    defer func() {h.close()}()

    h = &handler{i: 2}

}
2 close handler

類似於上面的指針,閉包不會發生改變,但是閉包所引用的值h可以發生改變

異常情況

在調用os.Exitlog.Fatal這些函數直接退出程序時,defer註冊的函數不會被執行

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