美文网首页golang学习
golang学习--defer

golang学习--defer

作者: 玖零儛 | 来源:发表于2020-03-01 21:51 被阅读0次

Go 语言中的 defer 语句,可以在函数结束或者是出现异常时保证执行相关释放资源的操作,和 C++中的析构函数有点类似。像是文件的关闭,socket 连接的关闭这些操作都可以使用 defer 语句来延迟执行。

特性

执行时机

  • 函数返回时(碰到的第一个 return 的位置)
  • 函数执行完毕(没有 return)
  • 函数碰到异常,抛出 panic 时
  • 调用 os.Exit 时 defer 不会被执行

执行顺序

  1. 返回值赋值给返回值变量,函数没有写返回值变量名则赋值给匿名变量
  2. 声明了 defer 语句的话就执行,有多个 defer 语句则按照声明顺序反过来分别执行
  3. 函数返回返回值 ret

延迟执行

  • defer 要先声明后才会延迟执行,如果函数已经走到 return,return 后面声明的 defer 语句是不会执行的
  • 如果有参数传递给 defer,值传递是在声明 defer 语句时就已经传值了,并不是在执行函数时去获取值

代码示例

返回结果判断

func ret1() int {
    x := 1
    defer func() {
        x++     //后执行,修改的是局部变量x
    }()
    return x    //先执行,匿名变量赋值为1
}

func ret2() (x int) {
    x = 1
    defer func() {
        x++     //修改了返回值
    }()
    return x    //返回值就是x
}

func TestRet(t *testing.T) {
    t.Log("ret1(): ", ret1())
    t.Log("ret2(): ", ret2())
}

// 执行结果:
// ret1():  1
// ret2():  2

defer 传入参数、多个 defer 执行顺序

func calc(index, a, b int) int {
    ret := a + b
    fmt.Println(index, a, b, ret)
    return ret
}

func TestParam(t *testing.T) {
    a := 1
    b := 2
    defer calc(1, a, calc(2, a, b)) // defer calc(1, 1, 3)
    a = 0
    defer calc(3, b, calc(4, a, b)) // defer calc(3, 2, 2)
    b = 1
}

// 执行结果:
// 2 1 2 3
// 4 0 2 2
// 3 2 2 4
// 1 1 3 4

执行时遇到 panic

func TestPanic(t *testing.T) {
    defer func() {
        t.Log("Clear resources")
    }()
    t.Log("Started")
    panic("Fatal error")
    t.Log("End")            //panic后不会执行
}

// 执行结果:
// Started
// Clear resources
// panic: Fatal error [recovered]

相关文章

  • Golang之Defer

    引用 golang defer实现原理 Golang之轻松化解defer的温柔陷阱 Golang中defer、re...

  • 2017-12-04

    Golang,Panic,Defer,Recover 在golang中,recover在defer里发挥作用。 一...

  • golang学习--defer

    Go 语言中的 defer 语句,可以在函数结束或者是出现异常时保证执行相关释放资源的操作,和 C++中的析构函数...

  • go defer理解

    golang的defer是怎么工作的?defer在golang里是一个很基础的关键字,在函数内部使用defer声明...

  • golang中defer执行时机与常见问题

    defer是什么? defer的用途 defer的执行时机 了解defer的执行时机首先要知道golang的ret...

  • 聊聊golang的defer

    序 本文主要研究一下golang的defer defer return先赋值(对于命名返回值),然后执行defer...

  • 12 Golang defer panic recover

    defer Golang中的defer会将其后面跟随的语句进行延迟处理。在defer归属的函数即将返回时,将延迟处...

  • 2017-11-23 step

    1 Golang的返回值,return,defer 多个defer的顺序是stack顺序,FILO 正确的顺序是:...

  • Golang defer

    话题起于同事在微信群里发了张图,是Go Newsletter于13日在Twitter上转的一个代码截图,问输出是啥...

  • golang defer

    The arguments to the deferred function (which include the...

网友评论

    本文标题:golang学习--defer

    本文链接:https://www.haomeiwen.com/subject/byolkhtx.html