go--函数调用--defer

知识点1: defer

defer知识点总结

官方文档

https://golang.org/ref/spec#Defer_statements

考点1:defer语句的执行顺序

defer语句的执行顺序如同栈一样,先进后出

  • 例1
// prints 3 2 1 0 before surrounding function returns
for i := 0; i <= 3; i++ {
    defer fmt.Print(i)
}

解答:
defer语句的执行顺序是是先进后出
输出 3 2 1 0

考点1 plus:defer语句与panic语句执行顺序

panic 需要等defer 结束后才会向上传递,所以会先执行defer语句然后执行panic

  • 例2
func defer_call() {
    defer func() { fmt.Println("打印前") }()
    defer func() { fmt.Println("打印中") }()
    defer func() { fmt.Println("打印后") }()

    panic("触发异常")
}

解答:
defer 是后进先出。
panic 需要等defer 结束后才会向上传递。 出现panic恐慌时候,会先按照defer的后入先出的顺序执行,最后才会执行panic。

打印后
打印中
打印前
panic: 触发异常

考点2: defer语句与return语句

注意return语句其实不是一个原子语句,可以拆分成 赋值语句与return 空 语句,赋值语句会在defer之前执行,而return 空语句会在defer执行完之后再执行。

  • 例1
// f returns 42
func f() (result int) {
    defer func() {
        // result is accessed after it was set to 6 by the return statement
        result *= 7
    }()
    return 6
}

解答:
该题目可以改写为

func f() (result int) {
        //赋值语
        result = 6
        defer func() {
            result *= 7
        }()
        //return 空语句
        return
}

这样就很容易看出来了,返回值其实是42而不是6

  • 例2
func f() (result int) {
    defer func() {
        result++
    }()
    return 0
}

解答:
返回值为1

考点3: defer语句与闭包

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

解答:
注意f()的入参是r, 而defer函数里的变量为t
拆分return t,可以得到 r=t语句,而且r并没有传入defer func()中,所以return的时候返回的是t的原始值,即5

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

解答:
拆分retun 1, 可以得到 r = 1, 然后r作为参数传入了defer func(r int)中, 所以会执行r = r + 5语句,然后再执行return语句。 即最后返回值为 6

考点4: defer保存副本

  • 例1
func hello(i int){
    fmt.Println(i)
}

func main(){
    i := 5
    defer hello(i)
    i = i + 10
}

输出:5
这个例子中,hello()函数的参数在执行defer语句的时候会保存一份副本。在实际调用hello()函数时用,所以是5

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Go语言defer关键字 defer关键字用于延缓函数的执行 只需要在调用普通函数或方法前加上关键字defer,就...
    楠小忎阅读 8,119评论 1 0
  • 参考文章:深入理解Go语言 defer用于资源的释放,会在函数返回之前进行调用 defer关键字的实现跟go关键字...
    小杰的快乐时光阅读 2,635评论 0 0
  • Go语言——defer defer操作类似stack,FILO先进后出。 与return一直使用的时候,需要注意顺...
    陈先生_9e91阅读 2,312评论 0 1
  • defer 通常认为defer就像真的被挪到了return之后。但defer的本质依然是函数调用。当执行到defe...
    mihope阅读 3,725评论 0 51
  • 先生今天发来一段视频,大概是说要注意身体健康大于一切的意思。 今天是我们俩两地分居的第62天,结婚那天我们就说好了...
    我是农妇阅读 1,189评论 0 2

友情链接更多精彩内容