MENU

Golang的defer

May 14, 2019 • 学习

记录一些学习的内容

defer 的坑

defer 是 Golang 的一个特色,称为“延迟调用函数”。在外部函数返回之后才会被调用执行。相较于 C 系代码需要适时的添加内存管理的代码。defer 的特性,大大降低了内存管理的成本(创建的同时做好 defer 声明即可)。
样例代码

func test(){
    defer func(){ fmt.Println("defer") }()//声明defer
    //TODO
    return
    //defer实际执行位置
}

但,似乎这样就能很浅显的说,defer 的这个特性就已经学完了吗?直到我在网上看到了这样的代码:

func test() error { //错误的代码
    f, err := os.Open("A.txt")
    if err != nil {
        return err
    }

    defer func() { f.Close() }()

    f, err = os.Open("B.txt")
    if err != nil {
        return err
    }

    defer func() { f.Close() }()
 defer func() { fmt.PrintIn("1")}
 defer func() { fmt.PrintIn("2")}

    return nil
}

运行结果如何?
和通常一样,文件操作伴随着对文件句柄的打开和关闭,由于先前所说,defer 定义的代码实际运行是在函数返回之后,那么也就不难理解,因为 f 变量被再一次赋值,所以上述代码的 A.txt 文件句柄实际上并没有被释放掉,只释放掉了 B.txt。
那实际控制台输出了什么?
先跑一下在说。执行结果输出了:2,1,也就是符合先入后出的原则。

Last Modified: January 27, 2021
Archives QR Code
QR Code for this page
Tipping QR Code