go语言中defer实例讲解

今天看李文周老师的博客讲解go语言defer关键字,我试着解读下两个实例

理论

defer执行时机

在Go语言的函数中return语句在底层并不是原子操作,它分为给返回值赋值和RET指令两步。而defer语句执行的时机就在返回值赋值操作后,RET指令执行前。具体如下图所示:
在这里插入图片描述

实例一:

func f1() int {
	x := 5
	defer func() {
		x++
	}()
	return x
}

func f2() (x int) {
	defer func() {
		x++
	}()
	return 5
}

func f3() (y int) {
	x := 5
	defer func() {
		x++
	}()
	return x
}
func f4() (x int) {
	defer func(x int) {
		x++
	}(x)
	return 5
}
func main() {
	//分析过程:定义x = 5,然后将返回值int赋值为x也就是5,此时defer函数执行,x变为6,但此时int值并不受影响(可以理解为两块内存地址),再执行RET所以返回值为5
	fmt.Println(f1())	// 5
	//分析过程:调用f2函数,将y返回值x 赋值为5,此时y执行defer函数将x 变为6,同时返回值变为6(可以理解为同一块内存地址),再执行RET所以返回值为6
	fmt.Println(f2())	// 6
	//分析过程:定义x = 5,然后将返回值y赋值为x也就是5,此时defer函数执行,x变为6,但此时y值并不受影响(可以理解为两块内存地址),再执行RET所以返回值为5
	fmt.Println(f3())	// 5
	//分析过程:defer注册要延迟执行的函数时该函数所有的参数都需要确定其值,因此在执行到defer时,x = 0。执行到return时,将 返回值x赋值为5,此时defer函数中x 变为1,但对返回值x没有影响(可以理解为两块内存地址), 再执行RET所以返回值为5
	fmt.Println(f4())	// 5
}

实例二:

package main

import "fmt"

func calc(index string, a, b int) int {
ret := a + b
fmt.Println(index, a, b, ret)
return ret
}

func main() {
x := 1
y := 2
defer calc("AA", x, calc("A", x, y))	//在执行到此处,因为y参数没有确定,因此首先会调用calc函数,运算得出y值。
x = 10
defer calc("BB", x, calc("B", x, y))	//在执行到此处,因为y参数没有确定,因此首先会调用calc函数,运算得出y值。
y = 20
}

执行结果

在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值