美文网首页
Golang中defer用法

Golang中defer用法

作者: DevilRoshan | 来源:发表于2020-03-09 00:27 被阅读0次

    Go语言中的defer语句会将其后面跟随的语句进行延迟处理。在defer归属的函数即将返回时,将延迟处理的语句按defer定义的逆序进行执行,也就是说,先被defer的语句最后被执行,最后被defer的语句,最先被执行。
    由于defer语句延迟调用的特性,所以defer语句能非常方便的处理资源释放问题。比如:资源清理、文件关闭、解锁及记录时间等。

    defer执行时机

    在Go语言的函数中return语句在底层并不是原子操作,它分为给返回值赋值和RET指令两步。而defer语句执行的时机就在返回值赋值操作后,RET指令执行前。具体如下图所示:

    defer运行时机.png

    return最先执行->return负责将结果写入返回值中->接着defer开始执行一些收尾工作->最后函数携带当前返回值退出

    defer 不带函数执行,defer可以理解像栈,先进后出

    func main()  {
        defer fmt.Println("one")  //第一个进入
        defer fmt.Println("two")  //第二进入
        defer fmt.Println("three") //第三个进入
    }
    // 按照先进后出的规则输出
    three
    two
    one
    

    defer带函数的执行,defer执行在返回赋值后,返回前执行

    func main() {
        fmt.Println(test())
    }
    
    func test() (res int) {
        res = 1
        defer func() {
            fmt.Println("start", res)
            res++
            fmt.Println("end", res)
        }()
        return 7
    }
    //
    start 7
    end 8
    8
    

    defer注册要延迟执行的函数时该函数所有的参数都需要确定其值

    func calc(index string, a, b int) int {
        ret := a + b
        fmt.Println(index, a, b, ret)
        return ret
    }
    func main() {
        x := 1
        y := 2
        defer calc("AA", x, calc("A", x, y))
        x = 10
        defer calc("BB", x, calc("B", x, y))
        y = 20
    }
    // defer注册要延迟执行的函数时该函数所有的参数都需要确定其值
    A 1 2 3
    B 10 2 12
    BB 10 12 22
    AA 1 3 4
    

    defer经典案例

    func f1() int {
        x := 5
        defer func() {
            x++
        }()
        return x
    }
    
    func f2() (x int) {
        defer func() {
            x++
        }()
        return 5
    }
    
    func f3() (y int) {
        x := 5
        defer func() {
            x++
        }()
        return x
    }
    func f4() (x int) {
        defer func(x int) {
            x++
        }(x)
        return 5
    }
    func main() {
        fmt.Println(f1())
        fmt.Println(f2())
        fmt.Println(f3())
        fmt.Println(f4())
    }
    // f1中x返回给return,x再自增跟return没有关系
    5
    // f2中x为return值,x自增仍被return
    6
    // f3中如f1
    5
    // f4defer中x的作用域为后面的参数x,值传递,不影响return的值
    5
    

    相关文章

      网友评论

          本文标题:Golang中defer用法

          本文链接:https://www.haomeiwen.com/subject/odmsdhtx.html