網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
Go 提供了兩種處理錯(cuò)誤 方式,
一 種是借助 panic和 recover 的拋出捕獲機(jī)制,
另一種使用error 錯(cuò)誤類型
一、異常
1、go沒有try/catch,而是使用panic/recover。
panic包出異常,后續(xù)代碼不再執(zhí)行
recover再defer中捕獲異常,使groutine(即程序)能夠正常退出。
1)只有panic,而沒有recover,程序宕機(jī)無(wú)法正常退出
package main import "fmt" func send(a, b int) int { if b == 0 { panic("wrong div") } c := a / b return c } func main() { defer func() { fmt.Println("wrong") }() send(1, 0) }
執(zhí)行結(jié)果:錯(cuò)誤
2) 正確情況,使用panic、recover
package main import "fmt" func send(a, b int) int { if b == 0 { panic("wrong div") } c := a / b return c } func main() { defer func() { fmt.Println("wrong") if err := recover(); err != nil { fmt.Println(err) // 這里的err其實(shí)就是panic傳入的內(nèi)容 } }() send(1, 0) fmt.Println("end") }
執(zhí)行結(jié)果:正常退出
2、panic被觸發(fā)的情況
1)用戶顯視調(diào)用panic
2)go內(nèi)部自動(dòng)檢測(cè)出空指針、數(shù)組越界等情況,會(huì)隱式報(bào)出panic,不需要用戶主動(dòng)調(diào)用
隱式例子如下:其實(shí)程序會(huì)自動(dòng)拋出異常,不需要寫panic語(yǔ)句
package main import "fmt" func send(a, b int) int { c := a / b return c } func main() { defer func() { fmt.Println("wrong") if err := recover(); err != nil { fmt.Println(err) // 這里的err其實(shí)就是panic傳入的內(nèi)容 } }() send(1, 0) fmt.Println("end") }
二、錯(cuò)誤
如果使用panic,最主要的是“報(bào)panic之后的函數(shù)都不會(huì)被執(zhí)行,由defer recover”
那么對(duì)于服務(wù)使用panic,那后面的業(yè)務(wù)就都不被執(zhí)行了,那假如這其實(shí)是個(gè)我自己寫的小錯(cuò)誤呢?
比如:我的程序不允許我自定義的變量為空,為空的話我難道直接panic?那假如我程序還有別的接口邏輯假如沒用到這個(gè)變量呢?直接panic豈不是服務(wù)掛了。
所以其實(shí)我能日志報(bào)出來(lái)這個(gè)錯(cuò)誤就行了——error
https://segmentfault.com/q/1010000020000806
go提供了接口類型error:
type error interface { Error() string }
故自定義錯(cuò)誤需要實(shí)現(xiàn)接口中的方法。
需要注意,方法的接受者如果是值,則調(diào)用相當(dāng)于進(jìn)行值拷貝,對(duì)副本進(jìn)行修改不會(huì)改變?cè)?/p>
方法的接受者是引用,相當(dāng)于傳遞的是變量的地址,原變量值才會(huì)被修改
package main import "fmt" type getName interface { printName() changeName() changeName2() } type dog struct { name string age int } type cat struct { name string age string } func (d dog) printName() { fmt.Println(d.name) } func (d dog) changeName() { d.name = "d2" } func (d *dog) changeName2() { d.name = "d2" } func (c cat) printName() { fmt.Println(c.name) } func main() { d := &dog{ name: "d1", age: 1, } d.printName() d.changeName() fmt.Println("changeName", d.name) d.changeName2() fmt.Println("changeName2", d.name) }
原文鏈接:https://blog.csdn.net/weixin_40906441/article/details/128660151
相關(guān)推薦
- 2022-03-23 C++實(shí)現(xiàn)水仙花數(shù)判斷實(shí)例_C 語(yǔ)言
- 2023-01-26 使用Jedis面臨的非線程安全問(wèn)題詳解_Redis
- 2022-08-08 pandas?給dataframe添加列名的兩種方法_python
- 2022-12-08 C++?Boost?Any示例分析使用_C 語(yǔ)言
- 2022-05-13 C++ 使用ffmpeg實(shí)現(xiàn)rtsp取流
- 2022-03-16 Linux系統(tǒng)中日志詳細(xì)介紹_Linux
- 2022-03-09 軟件構(gòu)建工具makefile基礎(chǔ)講解_C 語(yǔ)言
- 2022-06-07 C++11中跳轉(zhuǎn)initializer_list實(shí)現(xiàn)分析_C 語(yǔ)言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支