• golang defer未按预期顺序执行


    在golang项目开发中,使用到了defer,代码举例如下:

    func sum(i string, a, b int) int {
        ret := a + b
        fmt.Println(i)
        return ret
    }
    
    
    func main() {
        a := 1
        b := 2
        defer sum("1", a, sum("2", a, b))
        defer sum("3", a, b)
    }
    

      

    按照期望,defer先进后出的原则,应该是先打印出最后一个defer函数的值:

    3

    再打印第一个defer函数的值:

    2

    但实际打印是:

    2

    3

    1

    即第一个defer函数中的sum("2", a, b)最先被执行了,而不是我们想象中的只要是属于defer函数的内容都要等待执行。

     

     

     

    原因分析


    经过资料查找和测试,可以确定:当defer被声明时,其参数就会被实时解析,

    我们通过以下代码来解释这条规则:

    func a() {
        i := 0
        defer fmt.Println(i)
        i++
        return
    }
    

      



    运行结果是0


    这是因为虽然我们在defer后面定义的是一个带变量的函数: fmt.Println(i). 但这个变量(i)在defer被声明的时候,就已经确定其值了。

    这也是为什么本案例中的示例代码会先执行sum("2", a, b)了,效果是这样的:

    tmp := sum("2", a, b)
    defer sum("1", a, tmp)
    

      

     

    解决方案


    defer声明时,确保此时其参数的正确性,不使用不确定的变量作为入参。

  • 相关阅读:
    高性能无锁队列,代码注释
    阿里mysql同步工具otter的docker镜像
    webgl鱼眼算法
    国际网络环境对库的影响
    newlisp
    java面试之数据库
    java面试之遇到过的问题
    java面试之springboot
    git常用命令
    java面试之jenkins
  • 原文地址:https://www.cnblogs.com/yourstars/p/15186580.html
Copyright © 2020-2023  润新知