美文网首页
golang关于defer的问题

golang关于defer的问题

作者: 每天十分钟玩转测试 | 来源:发表于2019-06-27 16:14 被阅读0次

    要弄明白defer首先得搞清楚闭包和局部作用域。

    闭包

    闭包是匿名函数与匿名函数所引用环境的组合。
    看一个例子:

    func main() {
        n := 0
        f := func() {
            n += 1
        }
        f()
        fmt.Println("n = ", n)
    }
    
    // output:  n = 1
    
    func main() {
        n := 0
        f := func(n int) {
            n += 1
        }
        f(n)
        fmt.Println("n = ", n)
    }
    
    // output n = 0 
    

    看了以上两个例子,大概可以对闭包有个简单的认识,匿名函数可以直接引用上一级函数内的变量, 所以可以看到第一个例子进行 n+1 操作修改了main函数中的n的值。
    而第二个函数中的匿名函数需要传参n, 因为go中的传参都是值类型的, 所以不会修改外部变量n 输出扔为0。

    这篇文章的重点不是为了介绍闭包,所以这里只介绍这么多,有兴趣可以去网上找相关文章查阅。

    继续说defer

    • defer调用过程:
    1. 返回值为 xxx
    2. 调用defer函数
    3. return

    其实defer的调用相当于一个内部函数的调用,可以看以下例子:

    func f() (r int) {
        // go函数编译的时候已经将带名字的返回值变量给初始化
        // 所以在返回值的时候调用defer函数会改变其值
        r = 5
        defer func() {
            r = r + 5
        }()
        return
    }
    
    // output  10 
    // 与闭包中的第一个例子类似,defer 函数修改了r的值
    //  返回值r = 5
    // 调用defer函数 r += 5  => r = 10
    // return r => 10
    

    例2

    func f() (r int) {
        t := 5
        defer func() {
            t = t + 5
        }()
        return t
    }
    
    // 结合上边说的defer调用过程:
    //  返回值 r = t  对r进行赋值操作 
    // defer 修改 t 的值 t+= 5   =>   t =10
    // return r  => r = 5 
    

    例3

    func f() int {
        t := 5
        defer func() {
            t = t + 5
        }()
        return t
    }
    
    // 同样结合调用过程:
    // 返回值赋值 这里的返回值是个匿名变量, 假设这个匿名变量为NoName = t = 5
    // defer 调用  t+= 5  => t = 10
    // 返回 NoName = 5
    

    例4

    func f3() (r int) {
        // defer的时候 r为0
        defer func(r int) {
            r = r + 5
        }(r)
        return 1
    }
    
    // 结合defer调用过程
    // 返回值 r 赋值 r = 1 
    // 带参数r的匿名函数 进行defer调用, 参考闭包中的例子2 知道 r的传入不会影响外部r的值, 所以匿名函数外部的 r扔为1
    //  返回 r的值 1 
    

    以上, 即为defer的几种调用。

    文章内容有所参考, 如下:
    Golang之轻松化解defer的温柔陷阱

    相关文章

      网友评论

          本文标题:golang关于defer的问题

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