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注册的函数不会被执行

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