zoukankan      html  css  js  c++  java
  • golang中defer的些许总结

    引言

    最近自己在学习go项目的时候,查看别人的源码经常发现defer的使用,加上自己之前对这个关键字没怎么在意,只知道差不多是用来释放内部变量的。

    查看资料可以发现,defer会在当前函数或者方法返回之前执行传入的函数,经常用于关闭文件描述符、关闭数据库连接以及解锁资源

    为了能够更形象地理解defer的行为,我就在这贴上一段关闭文件描述符的示例代码:

    func CopyFile(source, dest string) bool {
        if source == "" || dest == "" {
            log.Println("source or dest is null")
            return false
        }
        source_open, err := os.Open(source)
        if err != nil {
            log.Println(err.Error())
            return false
        }
        defer source_open.Close()
        dest_open, err := os.OpenFile(dest, os.O_CREATE|os.O_WRONLY, 644)
        if err != nil {
            log.Println(err.Error())
            return false
        }
        defer dest_open.Close()
        _, copy_err := io.Copy(dest_open, source_open)
        if copy_err != nil {
            log.Println(copy_err.Error())
            return false
        } else {
            return true
        }
    }
    

    在示例代码中,使用了defer来关闭文件流,用来避免忘记文件释放的问题。

    defer的调用时机以及多次调用defer的执行顺序

    defer传入的函数会在当前调用方法返回之前得到运行。

    为了更好地解释上面的原理,通过一个简单例子来观察就很明显了:

    func main() {
        for i := 0; i < 4; i++ {
            defer fmt.Println(i)
        }   
    }
    

    示例程序中是用来循环输出数字的,实际上的运行结果如下,可以观察得出defer的效果类似于栈的先进后出:

    3 
    2 
    1 
    0
    

    defer的预计算参数

    defer继承了Go中函数调用的特性,就是函数调用都是传值的。所以,使用defer关键字之后,会立刻对函数中引用的外部参数进行拷贝

    示例程序如下,最后包含了输出结果:

    func PrintInfo() {
        val := 0
        fmt.Println("use defer to print val-->")
        // in here, will output 0
        defer fmt.Println(val)
        val++
        // in here, will output 1
        defer fmt.Println(val)
        return
    }
    
    use defer to print val--> 
    1 
    0
    

    至于程序为什么会输出1 0 而不是 0 1 ,答案已经在上面有了解释;

    参考资料

  • 相关阅读:
    记录下QCustomPlot 热力图的用法
    Qt QChart 创建图表
    Qt TCP 简单通信
    Qt 设置Qt::FramelessWindowHint 后界面无法移动问题的一种解决方案
    Qt 操作 Excel 的相关文档
    Microsoft Word Application Reference Qt 操作word 的操作文档
    Python 进行excel查重
    Qt QPainter画个球啊
    Redis持久性文档中文翻译
    Docker 课前预习
  • 原文地址:https://www.cnblogs.com/zuixime0515/p/13289087.html
Copyright © 2011-2022 走看看