关于golang的defer、 return、返回值三者的执行逻辑
来源:互联网 发布:tina仿真软件视频教程 编辑:程序博客网 时间:2024/05/16 16:15
无名返回值的情况
package mainimport ( "fmt")func main() { fmt.Println("return:", a()) // 打印结果为 return: 0}func a() int { var i int defer func() { i++ fmt.Println("defer2:", i) // 打印结果为 defer: 2 }() defer func() { i++ fmt.Println("defer1:", i) // 打印结果为 defer: 1 }() return i}
result
➜ test go run defer.go defer1: 1defer2: 2return: 0
有名返回值的情况
package mainimport ( "fmt")func main() { fmt.Println("return:", b()) // 打印结果为 return: 2}func b() (i int) { defer func() { i++ fmt.Println("defer2:", i) // 打印结果为 defer: 2 }() defer func() { i++ fmt.Println("defer1:", i) // 打印结果为 defer: 1 }() return i // 或者直接 return 效果相同}
result
➜ test go run defer01.go defer1: 1defer2: 2return: 2
结论
1.多个defer的执行顺序为“后进先出”;
2.defer、return、返回值三者的执行逻辑应该是:return最先执行,return负责将结果写入返回值中;接着defer开始执行一些收尾工作;最后函数携带当前返回值退出。
a()int 函数的返回值没有被提前声名,其值来自于其他变量的赋值,而defer中修改的也是其他变量,而非返回值本身,因此函数退出时返回值并没有被改变。
b()(i int) 函数的返回值被提前声名,也就意味着defer中是可以调用到真实返回值的,因此defer在return赋值返回值 i 之后,再一次地修改了 i 的值,最终函数退出后的返回值才会是defer修改过的值。
下面我们再来看第三个例子,验证上面的结论:
package mainimport ( "fmt")func main() { fmt.Println("c return:", *(c())) // 打印结果为 c return: 2}func c() *int { var i int defer func() { i++ fmt.Println("c defer2:", i) // 打印结果为 c defer: 2 }() defer func() { i++ fmt.Println("c defer1:", i) // 打印结果为 c defer: 1 }() return &i}
虽然 c()*int 的返回值没有被提前声明,但是由于 c()*int 的返回值是指针变量,那么在return将变量 i 的地址赋给返回值后,defer再次修改了 i 在内存中的实际值,因此函数退出时返回值虽然依旧是原来的指针地址,但是其指向的内存实际值已经被成功修改了。
func f() (result int) { defer func() { result++ }() return 0}
返回1
func f() (r int) { t := 5 defer func() { t = t + 5 }() return t}
返回的是5,而不是10,现将t的值赋予r,为5,接下来修改t,并不会修改r
func f() (r int) { defer func(r int) { r = r + 5 }(r) return 1}
返回的是1,而不是6,因为r是以值传递的方式传递到defer函数中去的,并不会导致r被修改
阅读全文
0 0
- 关于golang的defer、 return、返回值三者的执行逻辑
- Golang中defer、return、返回值之间执行顺序的坑
- Golang中defer、return、返回值之间执行顺序的坑
- golang中defer的执行
- go的defer和return执行顺序
- Go编程基础—defer、return、返回值之间执行顺序的坑
- golang的defer详解
- Golang有多个defer的情况
- golang中defer的详解
- golang-defer坑的本质
- 关于defer 的用法
- Golang defer 使用时的坑
- golang 使用defer、panic、recover的问题
- 请问关于 返回 return的问题
- python:关于函数返回return的问题
- finally语句是在try的return语句执行之后,return返回之前执行
- return与finally的执行顺序与返回值问题
- try--catch--finally中return返回值执行的顺序
- C语言算法6-15
- C语言基础知识学习(三)
- NOIP 2002普及组 过河卒详解
- Servlet中文乱码问题及其解决方法
- Currency Exchange(POJ1860 floyd)
- 关于golang的defer、 return、返回值三者的执行逻辑
- 一个转换流的方法
- 债券市场违约频繁发生 投资者要慎重选择标的
- pyspark.linalg模块学习
- Android之一个简单的NDK使用(一)
- webpack清除打包文件夹中多余的js文件
- 搭建STM32 的工程文件框架
- 【Codeforces】452F Permutation hash+线段树
- Android签名与认证原理