Golang的defer几个例子

52 阅读2分钟

先看下面代码:

func main() {
	fmt.Println("f2结果:", f2())
	fmt.Println("f3结果:", f3())
}

func f2() int {
	var a int
	defer func() {
		a++
		fmt.Println("---", a) //1
	}()
	return a
}

func f3() (a int) {
	defer func() {
		a++
	}()
	return a
}

运行结果:

--- 1
f2结果: 0
f3结果: 1 

f2和f3两个函数在返回值定义上不一样,f2是直接int,而f3是a  int,返回值就是a

defer和return的执行顺序:

从图中看出先执行返回值的赋值,然后执行defer语句,最后return

我们看看f2()函数执行流程:

首先定义一个变量a,默认值是0,然后defer延迟,接着往下是return a,进行图中顺序:返回值=a,此是a为0,也就是返回值=0,然后执行defer里面a加了1变为1,所以打印fmt.Println("---", a)结果为1,最后return结果返回值=0

我们看看f3()函数执行流程:

首先是defer延迟,然后return a,进行图中顺序:返回值=a=0,然后执行defer里面a++变为1,因为f3返回值定义是a int,所以返回值就是a,你现在在defer把a变为了1,那返回值就是1

扩展一下:

func main() {
	fmt.Println("add1结果:", add1(1, 2))
	fmt.Println("add2结果:", add2(1, 2))
}

func add1(x, y int) int {
	var z int
	defer func() {
		z = z + 9
		fmt.Println("add1---z=:", z)
	}()

	z = x + y
	return z + 200 // 执行顺序: (返回值 = z + 200) -> (call defer) -> (return)
}

func add2(x, y int) (z int) {
	defer func() {
		z = z + 9
		fmt.Println("add2---z=:", z)
	}()

	z = x + y
	return z + 200 // 执行顺序: (z = z + 200) -> (call defer) -> (return)
}

运行结果:

add1---z=: 12
add1结果: 203
add2---z=: 212
add2结果: 212 

add1()执行流程:

定义变量z默认值为0,然后defer延迟执行,接着z=x+y,此时z为3,然后return z+200,根据图中执行顺序:先给返回值赋值,返回值=(z+200)是一个整体,那么返回值是203,接着执行deferz=z+9那么z此时是3+9=12,最后把结果return,也就是z+200的值203返回。

add2()执行流程:

首先defer延迟执行,接着z=x+y,此时z为3,接着return z+200语句,我们知道f3返回值是z,先给返回值赋值,return z+200相当于z=z+200,那么z=203,然后执行defer里面的z=z+9=203+9=212,最后把返回值z返回给调用方,此时z为212,返回就是212