关闭

golang之defer

标签: golangdefer
199人阅读 评论(0) 收藏 举报
分类:

golang之defer

延迟调用函数defer的调用方式如下:

defer func_name(param_list)
  • 执行的时机
func f1() (ret int) {
    defer func() {
        ret++
    }()
    return 0
} 
func f2() (ret int) {
    temp := 1
    defer func() {
        temp += 10
    }()
    return temp
}
func f3() (ret int) {
    defer func(ret int) {
        ret += 10
    }(ret)
    return 1
}

先不要运行程序,心里记下自己认为分别运行这三个函数的结果,然后我们慢慢分析。

这里写图片描述

这里我们不分析defer的底层机制,只需知道它的实现效果。由于return语句并不是原子操作,它是分为两步来执行的:

(1)先在栈中写一个值,这个值被当做返回值;
(2)然后调用空的return语句。

有了defer之后,defer的执行是被插入在return之前赋值指令之后的

有了这个结论之后,我们来分析之前的代码结果:

f1():先给需要返回的值ret赋值为0,然后执行defer,将ret++,最后执行return语句返回1;

f2():将初始的temp=1赋值给temp,然后执行defer,temp+=10,此时返回的ret并不受temp的影响,最终结果仍然为1;

f3():return之前,先执行ret=1的赋值操作,然后,将ret 值传递给匿名函数,执行的结果不影响之前的值,所以ret函数最终的返回值是1。

  • 执行的顺序
func f4() {
    defer func() {
        fmt.Println("1-1")
        defer func() {
            fmt.Println("1-1-1")
        }()
    }()

    defer func() {
        fmt.Println("2-2")
        defer func() {
            fmt.Println("2-2-2")
        }()
    }()
}

结果如下:

这里写图片描述

可以看出它是基于先进后出的方式存储defer函数的,也就是逆序执行的。

0
0
查看评论

Golang中defer、return、返回值之间执行顺序的坑

Go语言中延迟函数defer充当着 cry...catch 的重任,使用起来也非常简便,然而在实际应用中,很多gopher并没有真正搞明白defer、return和返回值之间的执行顺序,从而掉进坑中,今天我们就来揭开它的神秘面纱! 先来运行下面两段代码: A. 无名返回值的情况 pac...
  • txj236
  • txj236
  • 2016-06-23 17:27
  • 2232

Golang defer 使用时的坑

defer是golang语言中的关键字,用于资源的释放,会在函数返回之前进行调用。一般采用如下模式: f,err := os.Open(filename) if err != nil { panic(err) } defer f.Close() 如果有多个defer表达式,调...
  • shenlanzifa
  • shenlanzifa
  • 2016-05-30 18:11
  • 1683

Golang有多个defer的情况

有多个defer时,return后先运行最后定义的defer,后进先出,栈的运行顺序 package main   import "fmt" import "log" func main(){ defer func() {...
  • muscledex
  • muscledex
  • 2017-05-04 21:59
  • 325

Go实战--golang中defer的使用(有事没事defer一下)

生命不止,继续 go go go !!!学习golang这么久了,还没看到类似传统的 try…catch…finally 这种异常捕捉方式。 但是,Go中引入的Exception处理:defer, panic, recover。那么今天跟大家分享一下golang中的defer。闲言少叙,看一下de...
  • wangshubo1989
  • wangshubo1989
  • 2017-07-04 21:28
  • 2727

golang中defer的详解

Go的defer语句用来调度一个函数调用(被延期的函数),使其在执行defer的函数即将返回之前才被运行,被延期执行的函数,它的参数(包括接受者)实在defer执行的时候被求值的,而不是在调用执行的时候。也就是说被延期执行的函数的参数是按正常顺序被求值的。    &#...
  • skh2015java
  • skh2015java
  • 2017-08-11 09:21
  • 453

golang中defer的执行

golang中defer的执行 大家都知道golang的defer关键字,它可以在函数返回前执行一些操作,最常用的就是打开一个资源(例如一个文件、数据库连接等)时就用defer延迟关闭改资源,以免引起内存泄漏。例如: func do() (ok bool) { file,_ := os....
  • wowzai
  • wowzai
  • 2014-03-13 20:39
  • 2235

go语言defer使用

defer Go语言中有种不错的设计,即延迟(defer)语句,你可以在函数中添加多个defer语句。当函数执行到最后时,这些defer语句会按照逆序执行,最后该函数返回。特别是当你在进行一些打开资源的操作时,遇到错误需要提前返回,在返回前你需要关闭相应的资源,不然很容易造成资源泄露等问题。如下代...
  • eclipser1987
  • eclipser1987
  • 2013-09-27 12:53
  • 23085

关于Go的闭包、匿名函数和defer的结合使用案例分析

Go里的“析构函数”defer关键字类似于PHP的__destruct(),用来标记最后执行的Go语句,一般用在资源释放、关闭连接等操作,会在函数关闭前调用。多个defer的定义与执行类似于栈的操作:先进后出,最先定义的最后执行。在defer的使用中,碰到过许多坑,尤其是在defer与匿名函数搭配使...
  • qq_27682041
  • qq_27682041
  • 2017-12-13 11:33
  • 107

Go语言defer的使用

转载:http://cloudnil.com/2014/05/19/defer-in-go/ Go语言中没有类似于java中的try…catch…finally的语句块,但是却有一个非常优雅的defer。 defer关键字用来标记最后执行的Go语句,一般用在资源释放、关闭连接等操作,...
  • yugongpeng_blog
  • yugongpeng_blog
  • 2015-04-14 12:04
  • 695

golang中的defer panic recover

大家都知道golang里的panic相当于其他语言里的throw,而recover相当于其他语言里的cacth,可是由于golang的recover机制要求必须在defer的函数里才能执行catch panic 大概意思如下 func protect(g func()) { def...
  • HopingWhite
  • HopingWhite
  • 2013-04-18 10:22
  • 3668
    个人资料
    • 访问:6257次
    • 积分:368
    • 等级:
    • 排名:千里之外
    • 原创:31篇
    • 转载:7篇
    • 译文:0篇
    • 评论:2条
    文章分类
    最新评论