golang的defer详解

来源:互联网 发布:可以编辑照片的软件 编辑:程序博客网 时间:2024/06/05 01:12
###代码
先阅读一下代码,然后给出答案,之后在运行,看看结果是否一致,如果一致,不用往下看了,你已经懂deferpackage mainfunc main() {    println(example1(1))    println(example2(1))    println(example3(1))    println(example4())    println(example5())    println(example6())}func example1(i int) (t int) {    t = i    defer func() {        t += 3    }()    return t}func example2(i int) int {    t := i    defer func() {        t += 3    }    return t}func example3(i int) (t int) {    defer func() {        t += i    }()    return 2}func example4() (result int) {    defer func() {        result++    }()    return 0}func example5() int {    t := 5    defer func() {        t = t + 5    }()    return t}func example6() (r int) {    defer func(r int) {        r = r + 5    }(r)    return 1}

解析

首先您觉得是defer和return哪个先执行呢?首先要明确的是:defer是在return之前执行的这是官方文档中明确说明的http://golang.org/ref/spec#Defer_statements ,知道就行了,可以无视整个return过程,没有defer之前是,先把在栈中写一个值,这个值被会当作返回值。然后再调用RET指令返回。return xxx语句汇编后是先给返回值赋值,再做一个空的return: ( 赋值指令 + RET指令)defer的执行是被插入到return指令之前的有了defer之后,就变成了 (赋值指令 + CALL defer指令 + RET指令)上面这几句话是从别的地方贴过来的。也就是说:看完之后来一一解释一下上面的几个函数(1)先在栈中写一个值,这个值被当做返回值; (2)然后调用空的return语句。(3)需要注意的是看defer func里面修改的是返回的变量还是修改的别的变量,这里容易理解错误,例如example2example1 函数返回值t作用域为整个函数,在return之前defer会被执行,所以t会被修改,返回4;example2 可以写成下面这样,首先给x赋值=1,defer修改t的值=4,但是不修改x最终结果仍然为1;func example2(i int) x int {t := idefer func() {    t += 3}return t}example3 修改为下面这样写就方便理解了,返回3;func example3(i int) (t int) {    t = 2    defer func() {        t += i    }()    return}example4 同example3,返回1example5 修改一下代码写成下边这样;defer func修改的不是r,返回5;func example5() (r int) {t := 5defer  func() {    t = t + 6}()fmt.Println(t)return t}example6 defer执行的func传入的参数相当于赋值,不会改变原来的值,返回1;
如果有不对的理解欢迎批评指出。