golang的defer详解

###代码
先阅读一下代码,然后给出答案,之后在运行,看看结果是否一致,如果一致,不用往下看了,你已经懂deferpackage main
func 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里面修改的是返回的变量还是修改的别的变量,这里容易理解错误,例如example2

example1 函数返回值t作用域为整个函数,在return之前defer会被执行,所以t会被修改,返回4;
example2 可以写成下面这样,首先给x赋值=1,defer修改t的值=4,但是不修改x最终结果仍然为1;
func example2(i int) x int {
t := i
defer func() {
    t += 3
}
return t
}
example3 修改为下面这样写就方便理解了,返回3;
func example3(i int) (t int) {
    t = 2
    defer func() {
        t += i
    }()
    return
}
example4 同example3,返回1
example5 修改一下代码写成下边这样;defer func修改的不是r,返回5;
func example5() (r int) {
t := 5
defer  func() {
    t = t + 6
}()
fmt.Println(t)
return t
}

example6 defer执行的func传入的参数相当于赋值,不会改变原来的值,返回1;
如果有不对的理解欢迎批评指出。

猜你喜欢

转载自blog.csdn.net/mofiu/article/details/78391156