• 技术文章 >后端开发 >Golang

    go语言defer的用法是什么

    我叫mt我叫mt2021-01-07 15:23:13原创785

    go语言defer的用法:1、defer语句在函数返回之前或函数中的return语句之后执行;2、多个defer语句的执行顺序是逆序执行;3、在panic语句后的defer语句不执行。

    本文操作环境:windows10系统、GO 1.11.2、thinkpad t480电脑。

    (学习视频分享:编程视频

    用法介绍:

    defer是Go语言中的延迟执行语句,用来添加函数结束时执行的代码,常用于释放某些已分配的资源、关闭数据库连接、断开socket连接、解锁一个加锁的资源。Go语言机制担保一定会执行defer语句中的代码。

    其它语言中也有类似的机制,比如Java、C#语言里的finally语句,C++语言里的析构函数(Destructor)可以起类似的作用,C++语言机制担保在对象被销毁前一定会执行析构函数中的代码。C++中的析构函数析构的是对象,Go中的defer析构的是函数。

    一、defer语句执行时机

    defer语句在函数返回之前 或者 函数中 return语句(return语句可能调用另一个函数) 之后执行。示例代码:

    package main
     
    import (
        "fmt"
    )
     
    func main() {
        fmt.Println(deferReturn())
    }
     
    func deferReturn() (ret int) {
        defer func() {
            ret++
        }()
        return 10
    }

    上述代码打印出来的值是:11。 defer语句 匿名函数中的“ret++” 对返回值 10 加 1 变成了 11。再来看一个defer语句出现在return语句之后的代码:

    func returnDefer() (ret int) {
        return 0
        defer func() {
            ret++
            ret++
        }()
        return 1
    }

    上述returnDefer函数的返回值是:0。原因是defer语句还没有添加上代码执行到"return 0"函数就返回了,因此defer语句就没有执行。

    二、多个defer语句的执行顺序是逆序执行

    当出现多条 defer 语句时以逆序执行(类似栈,即后进先出)。示例代码:

    func deferSample() {
        for i := 0; i < 5; i++ {
            defer fmt.Printf("%d ", i)
        }
    }

    上述代码将会输出:4 3 2 1 0

    三、defer与panic

    1、在panic语句后面的defer语句不被执行

    示例代码:

    func panicDefer() {
        panic("panic")
        defer fmt.Println("defer after panic")
    }

    上述代码的输出如下:

    panic: panic
    goroutine 1 [running]:
    main.panicDefer()
        E:/godemo/testdefer.go:17 +0x39
    main.main()
        E:/godemo/testdefer.go:13 +0x20
    Process finished with exit code 2

    可以看到 defer 语句没有执行。

    2、在panic语句前的defer语句会被执行

    示例代码:

    func deferPanic() {
        defer fmt.Println("defer before panic")
        panic("panic")
    }

    上述代码的输出如下:

    defer before panic
    panic: panic
    goroutine 1 [running]:
    main.deferPanic()
        E:/godemo/testdefer.go:19 +0x95
    main.main()
        E:/godemo/testdefer.go:14 +0x20
    Process finished with exit code 2

    defer 语句输出了内容。

    Go中的panic类似其它语言中的抛出异常,panic后面的代码不再执行(panic语句前面的defer语句会被执行)。

    四、return 的实现逻辑

    1、第一步给返回值赋值(若是有名返回值直接赋值,匿名返回值 则 先声明再 赋值) ;
    2、第二步调用RET返回指令并传入返回值,RET会检查是否存在defer语句,若存 在就先逆序插播 defer语句 ;
    3、最后 RET 携带返回值退出函数 。

    可以看出 , return 不是一个原子操作,函数返回值与 RET 返回值并不一定一致。

    五、defer、 return、返回值三者顺序

    defer、 return、返回值 三者的执行顺序是 : return 最先给返回值赋值;接着 defer 开始执行一些收尾工作;最后 RET 指令携带返回值退出函数。

    相关推荐:golang教程

    以上就是go语言defer的用法是什么的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:go语言 defer 用法
    上一篇:windows下怎么搭建go语言开发环境 下一篇:go语言是啥
    PHP编程就业班

    相关文章推荐

    • golang中的defer关键字什么时候生效• jQuery.Deferred() 详解• 一起了解script标签中的async和defer属性• jquery中deferred对象是什么?

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网