Golang中defer的三个实战要点
Posted 咖啡色的羊驼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang中defer的三个实战要点相关的知识,希望对你有一定的参考价值。
前言
Golang中的defer是使用频次比较高的,能创造出延迟生效特效的一种方式。
defer也有自己的矫情,需要注意的。
本文将从通过代码的方式来说明defer的三点矫情。
1.defer的生效顺序
2.defer与return,函数返回值之间的顺序
3.defer定义和执行两个步骤,做的事情。
正文
1.defer的生效顺序
先说结论:defer的执行顺序是倒序执行(同入栈先进后出)
func main()
defer func()
fmt.Println("我后出来")
()
defer func()
fmt.Println("我先出来")
()
执行后打印出:
我先出来
我后出来
2.defer与return,函数返回值之间的顺序
先说结论:return最先执行->return负责将结果写入返回值中->接着defer开始执行一些收尾工作->最后函数携带当前返回值退出
返回值的表达方式,我们知道根据是否提前声明有两种方式:一种是func test() int 另一种是 func test() (i int),所以两种情况都来说说
func test() int
func main()
fmt.Println("main:", test())
func test() int
var i int
defer func()
i++
fmt.Println("defer2的值:", i)
()
defer func()
i++
fmt.Println("defer1的值:", i)
()
return i
输出:
defer1的值: 1
defer2的值: 2
main: 0
详解:return的时候已经先将返回值给定义下来了,就是0,由于i是在函数内部声明所以即使在defer中进行了++操作,也不会影响return的时候做的决定。
func test() (i int)
func main()
fmt.Println("main:", test())
func test() (i int)
defer func()
i++
fmt.Println("defer2的值:", i)
()
defer func()
i++
fmt.Println("defer1的值:", i)
()
return i
输出:
defer1的值: 1
defer2的值: 2
main: 2
详解:由于返回值提前声明了,所以在return的时候决定的返回值还是0,但是后面两个defer执行后进行了两次++,将i的值变为2,待defer执行完后,函数将i值进行了返回。
3.defer定义和执行两个步骤,做的事情
先说结论:会先将defer后函数的参数部分的值(或者地址)给先下来【你可以理解为()里头的会先确定】,后面函数执行完,才会执行defer后函数的中的逻辑
func test(i *int) int
return *i
func main()
var i = 1
// defer定义的时候test(&i)的值就已经定了,是1,后面就不会变了
defer fmt.Println("i1 =" , test(&i))
i++
// defer定义的时候test(&i)的值就已经定了,是2,后面就不会变了
defer fmt.Println("i2 =" , test(&i))
// defer定义的时候,i就已经确定了是一个指针类型,地址上的值变了,这里跟着变
defer func(i *int)
fmt.Println("i3 =" , *i)
(&i)
// defer定义的时候i的值就已经定了,是2,后面就不会变了
defer func(i int)
//defer 在定义的时候就定了
fmt.Println("i4 =" , i)
(i)
defer func()
// 地址,所以后续跟着变
var c = &i
fmt.Println("i5 =" , *c)
()
// 执行了 i=11 后才调用,此时i值已是11
defer func()
fmt.Println("i6 =" , i)
()
i = 11
如果你觉得有收获~可以关注我的公众号【咖啡色的羊驼】~第一时间收到我的分享和知识梳理~
以上是关于Golang中defer的三个实战要点的主要内容,如果未能解决你的问题,请参考以下文章