defer的用法
defer的用法
1.清理釋放資源
由于 defer 的延遲特性,defer 常用在函數(shù)調(diào)用結(jié)束之后清理相關(guān)的資源,如:
f, _ := os.Open(filename)
defer f.Close()
2.執(zhí)行 recover
被 defer 的函數(shù)在 return 之后執(zhí)行,這個(gè)時(shí)機(jī)點(diǎn)正好可以捕獲函數(shù)拋出的 panic,因而 defer 的另一個(gè)重要用途就是執(zhí)行 recover。
(1.) panic 能夠改變程序的控制流,調(diào)用 panic 后會(huì)立刻停止執(zhí)行當(dāng)前函數(shù)的剩余代碼,并在當(dāng)前 Goroutine 中遞歸執(zhí)行調(diào)用方的 defer;
(2.) recover 可以中止 panic 造成的程序崩潰。它是一個(gè)只能在 defer 中發(fā)揮作用的函數(shù),在其他作用域中調(diào)用不會(huì)發(fā)揮作用;
(3.) panic 只會(huì)觸發(fā)當(dāng)前 Goroutine 的 defer;
(4.) recover 只有在 defer 中調(diào)用才會(huì)生效;
(5.)panic 允許在 defer 中嵌套多次調(diào)用;
// 打印堆棧信息
defer func() {
if err := recover(); err != nil {
Log.Error("server panic,err:%v", err)
for i := 0; ; i++ {
pc, file, line, ok := runtime.Caller(i)
if !ok {
break
}
Log.Error("server panic,pc:%v
,file:%v
,line:%v
", pc, file, line)
}
}
}()
3.后進(jìn)先出
多個(gè)defer出現(xiàn)的時(shí)候,它是一個(gè)“棧”的關(guān)系,也就是先進(jìn)后出。一個(gè)函數(shù)中,寫在前面的defer會(huì)比寫在后面的defer調(diào)用的晚。
defer func() { fmt.Println("1") }()
defer func() { fmt.Println("2") }()
defer func() { fmt.Println("3") }()
// 執(zhí)行結(jié)果:3 2 1
4.修改帶名稱的返回值
return之后的語句先執(zhí)行,defer后的語句后執(zhí)行
func c() (i int) {
defer func() { i++ }()
return 1
}
// 返回值:2
參考鏈接
https://draveness.me/golang/docs/part2-foundation/ch05-keyword/golang-panic-recover/
https://juejin.cn/post/6844903936508297223
【勵(lì)志篇】:
古之成大事掌大學(xué)問者,不惟有超世之才,亦必有堅(jiān)韌不拔之志。
總結(jié)
- 上一篇: PythonOpencv-分类器—SVM
- 下一篇: ios安装app提示【未受信任的企业级开