go语言中defer,defer的执行时机,非命名返回值和命名返回值的区别
Go语言中的 defer 语句会将其后面跟随的语句进行延迟处理。
先被defer的语句最后被执行,最后被defer的语句最先被执行。
package main
import ("fmt")
func main() {
fmt.Println("开始")
defer fmt.Println("1")
defer fmt.Println("2")
fmt.Println("结束")
}
开始
结束
2
1
defer语言的执行时机
go-1png
defer在函数中的使用(非命名返回值)
package main
import ("fmt")
func f2() int {
var a =10
// 这里使用 defer
defer func(){
a++
}()
return a
}
func main() {
fmt.Println(f2())
}
输出:10
defer在函数中的使用(命名返回值 + defer 执行时机)
package main
import ("fmt")
func f2() (a int){
defer func(){
a++
}()
return a
}
func main() {
fmt.Println(f2())
}
输出的值是:1
分析:
考察的是:命名返回值 + defer 执行时机
func f2() (a int) {}这里 a 是命名返回值;
它相当于在函数开头隐式声明了一个变量 a;
并且这个 a 是函数返回时实际返回的那个变量。
return 不是原子操作;
return a 在底层其实分为两步:
1,赋值:把要返回的值赋给命名返回值 a(这里是自己赋值给自己,a = a)
2,执行 defer:运行所有 defer 函数
3,真正返回:把 a 的值返回给调用者
执行流程
- a 初始为 0
- return a → 把 a(=0) 赋值给返回值 a(还是 0)
- 执行 defer → a++ → a 变成 1
- 函数返回 a = 1
所以最终输出 1
总结:非命名返回值和命名返回值的区别
命名返回值让 defer 有机会修改最终返回的值;
return 会先给命名返回值赋值,再执行 defer,
所以 defer 里的 a++ 会影响到最终返回结果。
怎么区分是命名返回值和非命名返回值
括号里是 名字 类型 的形式就是:命名返回值
func f() (a int) { ... } // 返回 1 个,名字 a
func g() (x, y int) { ... } // 返回 2 个,名字 x, y
func h() (err error) { ... } // 名字 err
非命名返回值(只有类型):括号里只有类型,没有变量名。
func f() int { ... } // 只有类型
func g() (int, string) { ... } // 只有类型
func h() error { ... } // 只有类型
作者:流年少年
出处:https://www.cnblogs.com/ishoulgodo/
本文版权归作者所有,欢迎转载,未经作者同意须保留此段声明,在文章页面明显位置给出原文连接
如果文中有什么错误,欢迎指出。以免更多的人被误导。
出处:https://www.cnblogs.com/ishoulgodo/
想问问题,打赏了卑微的博主,求求你备注一下的扣扣或者微信;这样我好联系你;(っ•̀ω•́)っ✎⁾⁾!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,或者关注博主,在此感谢!
万水千山总是情,打赏5毛买辣条行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主(っ•̀ω•́)っ✎⁾⁾!
想问问题,打赏了卑微的博主,求求你备注一下的扣扣或者微信;这样我好联系你;(っ•̀ω•́)っ✎⁾⁾!
支付宝
微信
如果文中有什么错误,欢迎指出。以免更多的人被误导。

浙公网安备 33010602011771号