Loading

Go 彻底弄懂return和defer的微妙关系

package main
import "fmt"
func main()  {
	fmt.Println("f1 result: ", f1())
    fmt.Println("f2 result: ", f2())
}
func f1() int {
    var i int
    defer func() {
        i++
        fmt.Println("f11: ", i)
    }()
    i = 1000
    return i
}
func f2() (i int) {
    defer func() {
        i++
        fmt.Println("f21: ", i)
    }()
    i = 1000
    return i
}

f1函数:

  进入该函数,因为没有指定返回值变量,需要先声明i变量,因为是int类型,如果没有赋值,该变量初始化值为0,之后执行i=1000的赋值操作,然后执行return语句,返回i的值。

  真正返回之前还要执行defer函数部分,返回1000

f2函数:

  进入该函数,因为已经定义好了返回值变量即为i,然后直接赋值i=1000,再返回i的值。

  同样的,也要在真正返回i前,执行defer函数,同样i依次自增得到1001

  问题的关键是为什么无名参数返回的值是1000,其并未收到defer函数对于i自增的影响;而有名函数在执行defer后,最后返回的i值为1001。

原因就是return会将返回值先保存起来,对于无名返回值来说,
保存在一个临时对象中,defer是看不到这个临时对象的;
而对于有名返回值来说,就保存在已命名的变量中。

 

posted @ 2020-08-12 15:13  Allfuture  阅读(245)  评论(0编辑  收藏  举报