go defer 使用规则

defer

用于延迟函数的调用,每次defer都会把一个函数压入栈中,函数返回前再把延迟的函数取出并执行

规则一:延迟函数的参数在defer语句出现时就已经确定下来了

如:

func a() {
    i := 0
    defer fmt.Println(i)
    i++
    return
}

defer语句中的fmt.Println()参数i值在defer出现时就已经确定下来,实际上是拷贝了一份。后面对变量i的修改不会影响fmt.Println()函数的执行,仍然打印”0”。但是注意 这里对于指针类型参数,仍然适用,所以defer后面的语句对变量修改还是会影响延迟函数如:

func a() {
	i := []int{1,2,3}
	defer fmt.Println(i)
	i[0]=10
	return
}//会输出[10,2,3],因为这里i为指针,是数组的地址

规则二:先进后出

很好理解,延迟函数执行按先进后出顺序执行,即先进去的defer最后执行

规则三:延迟函数可能操作主函数的具名返回值

defer可能会改变返回值,因为return语句不是原子的,实际执行为设置返回值–>ret

defer语句实际执行在返回前,即拥有defer的函数返回过程是:设置返回值–>执行defer–>ret。

注意:这里返回值必须要有具体名字

如下:

func deferFuncReturn() (result int) {
    i := 1

    defer func() {
       result++
    }()

    return i
}

输出2,return语句先把result设置为i的值,即1,defer语句又把result递增1,所以最终返回2

如果返回的是匿名变量,则不改变,如:

func foo() int {
	var i int

	i=1
	defer func() {
		i++
	}()

	return i
}

这里还是返回1,上面的返回语句可以拆分成以下过程:

t=i	//t就是要返回的值
i++
return //返回t,这里t还是1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值