zoukankan      html  css  js  c++  java
  • GO语言学习笔记5-defer的使用

    什么是defer

    defer是Go语言提供的一种用于注册延迟调用的机制:让函数或语句可以在当前函数执行完毕后(包括通过return正常结束或者panic导致的异常结束)执行。

    defer的应用场景

    defer语句通常用于一些成对操作的场景:打开连接/关闭连接;加锁/释放锁;打开文件/关闭文件等。

    defer的原理

    defer语句并不会马上执行,而是会进入一个栈,函数return前,会按先进后出(FILO)的顺序执行。也就是说最先被定义的defer语句最后执行。先进后出的原因是后面定义的函数可能会依赖前面的资源,自然要先执行;否则,如果前面先执行,那后面函数的依赖就没有了。

    defer的引用方式

    defer语句定义时,对外部变量的引用有如下两种方式:

    1.作为函数参数和作为闭包引用。作为函数参数,则在defer定义时就把值传递给defer,并被缓存起来。
    2.作为闭包引用的话,则会在defer函数真正调用时根据整个上下文确定当前的值。

    defer的踩坑点

    避免踩坑的关键是要理解这条语句:

    return xxx
    

    这条语句经过编译之后,会变成了三条指令:

    1. 返回值 = xxx
    2. 调用defer函数
    3. 空的return
    

    第1,3 步才是return 语句真正的命令,第2步是 defer的定义语句,这里就有可能会操作返回值。

    代码示例

    示例1:

    func f() (r int) {
        defer func() {
            r++
        }()
        return 0
    }
    

    拆解过程:

    func f() (r int) {
    
        // 1.赋值
        r = 0
    
        // 2.闭包引用,返回值被修改
        defer func() {
            r++
        }()
    
        // 3.空的return
        return
    }
    

    由于defer是闭包引用,返回值被修改,所以f()返回 1。

    示例2:

    func f() (r int) {
        t := 5
        defer func() {
            t = t + 5
        }()
        return t
    }
    

    拆解过程:

    func f() (r int) {
        t := 5
        // 1.赋值
        r = t
    
        // 2.闭包引用,但是没有修改返回值r
        defer func() {
            t = t + 5
        }()
    
        // 3.空的return
        return
    }
    

    由于第2步未涉及返回值r的操作,所以返回5。

    示例3:

    func f() (r int) {
        defer func(r int) {
            r = r + 5
        }(r)
        return 1
    }
    

    拆解过程:

    func f() (r int) {
    
        // 1.赋值
        r = 1
    
        // 2.r作为函数参数,不会修改要返回的那个r值
        defer func(r int) {
            r = r + 5
        }(r)
    
        // 3.空的return
        return
    }
    

    由于第2步中r是作为函数参数使用,只是一份拷贝,defer语句里面的r和外面的r其实是两个变量,里面变量r的改变不会影响外层变量r,所以不是返回6,而是返回1。


    个人主页:

    www.codeapes.cn

  • 相关阅读:
    csharp: Speech
    软件定义网络基础---OF-Config协议
    软件定义网络基础---OpenFlow协议
    软件定义网络基础---南向接口协议概述
    Win10+Ubuntu18.04安装双系统
    软件定义网络基础---OpenFlow流表
    软件定义网络基础---OpenFlow概述
    软件定义网络基础---SDN数据平面
    软件定义网络基础---SDN的核心思想
    软件定义网络基础---SDN的主流构架
  • 原文地址:https://www.cnblogs.com/codeapes666/p/12093811.html
Copyright © 2011-2022 走看看