Go ---- defer 和 return 执行的先后顺序

Go 中 defer 和 return 执行的先后顺序

1. defer 与 defer 之间服从先进后出原则

2. defer 和 return之间的顺序是先返回值,后defer

3. 理解return 返回值的运行机制:

 

eg1:不带命名返回值的函数

package main

import "fmt"

func main() {
	fmt.Println("return:", test())// defer 和 return之间的顺序是先返回值, i=0,后defer
}

func test() int {//这里返回值没有命名
	var i int
	defer func() {
		i++
		fmt.Println("defer1", i) //作为闭包引用的话,则会在defer函数执行时根据整个上下文确定当前的值。i=2
	}()
	defer func() {
		i++
		fmt.Println("defer2", i) //作为闭包引用的话,则会在defer函数执行时根据整个上下文确定当前的值。i=1
	}()
	return i
} 

test() 先返回 i=0

defer2先于defer1执行

输出结果为:

defer2 1

defer1 2

return: 0

 

 

eg2:带命名返回值的函数:

package main

import "fmt"

func main() {
	fmt.Println("return:", test())
}

func test() (i int) { //返回值命名i 
	defer func() {
		i++
		fmt.Println("defer1", i)
	}()
	defer func() {
		i++
		fmt.Println("defer2", i)
	}()
	return i
}
对外部变量的引用作为函数参数(i),则在defer申明时就把值传递给defer,

 

 输出结果为:

defer2 1

defer1 2

return: 2

理解return 返回值的运行机制:

为了弄清上述两种情况的区别,我们首先要理解return 返回值的运行机制:
return 并非原子操作,分为赋值,和返回值两步操作
eg1 : 实际上return 执行了两步操作,因为返回值没有命名,所以
return 默认指定了一个返回值(假设为s),首先将i赋值给s,后续
的操作因为是针对i,进行的,所以不会影响s, 此后因为s不会更新,所以
return s 不会改变
相当于:
var i int
s := i
return s
eg2 : 同上,s 就相当于 命名的变量i, 因为所有的操作都是基于
命名变量i(s),返回值也是i, 所以每一次defer操作,都会更新
返回值i

 

 

上一篇:defer func(参数){}


下一篇:我为什么选择go语言