為了方便實現(xiàn)自定義錯誤類型,Go語言標(biāo)準(zhǔn)庫中將error定義為接口類型。比如:
成都網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)建站!專注于網(wǎng)頁設(shè)計、成都網(wǎng)站建設(shè)、微信開發(fā)、微信平臺小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。核心團(tuán)隊均擁有互聯(lián)網(wǎng)行業(yè)多年經(jīng)驗,服務(wù)眾多知名企業(yè)客戶;涵蓋的客戶類型包括:成都衛(wèi)生間隔斷等眾多領(lǐng)域,積累了大量豐富的經(jīng)驗,同時也獲得了客戶的一致稱揚!type error interface{ Error() string }
按照Go語言編程習(xí)慣,error總是最后一個函數(shù)返回值,并且標(biāo)準(zhǔn)庫提供了創(chuàng)建函數(shù),可以方便的創(chuàng)建錯誤消息的error對象。比如:
func divTest(x ,y int)(int, error){ if y == 0{ return 0, errors.New("division by zero") //創(chuàng)建錯誤消息的error對象 } return x/y,nil } func main(){ v, err := divTest(3,0) if err != nil{ log.Fatalln(err.Error()) } println(v) }
日常開發(fā)中,我們需要根據(jù)需求自定義錯誤類型,可以存放更多的上下文信息,或者根據(jù)錯誤類型做出相應(yīng)的錯誤處理。比如:
type NegativeError struct{ x, y int } func (NegativeError)Error()string{ return "negative value error" } type MolError struct { x, y int } func (MolError)Error()string{ return "devision by zero" } func molTest(x ,y int)(int, error){ if y == 0{ return 0, MolError{x,y} } if x < 0 || y < 0{ return 0, NegativeError{x,y} } return x%y,nil } func main(){ v, err := molTest(3,-1) if err != nil{ switch e := err.(type){ //獲取錯誤類型 case MolError: println(e.x,e.y) case NegativeError: println(e.x,e.y) default: println(e) } log.Fatalln(err.Error()) } println(v) }
與error相比,panic/recover 在應(yīng)用上更類似于 try/catch 結(jié)構(gòu)化。比如:
func panic() interface{} func recover() interface{}
兩者區(qū)別:panic 立即中斷當(dāng)前函數(shù)處理流程,執(zhí)行延遲調(diào)用。recover在延遲調(diào)用中可以捕獲并返回panic產(chǎn)生的錯誤對象,比如:
func Myrecover(){ if err := recover(); err != nil{ log.Fatalln(err) } } func main(){ println("start...") defer Myrecover() panic("dead") println("end...") } 輸出: start... 2017/02/09 11:24:13 dead exit status 1
如果有連續(xù)多次調(diào)用panic的場景,只有最后一次panic會被recover捕獲處理,比如:
func Myrecover(){ if err := recover(); err != nil{ log.Fatalln(err) } } func main(){ defer Myrecover() defer func(){ panic("a bad problem") }() panic("a problem") } 輸出: 2017/02/09 11:31:50 a bad problem exit status 1
recover只有在延遲調(diào)用函數(shù)中才能得到正常工作,比如:
func main() { defer Myrecover() defer log.Println(recover()) defer println(recover()) panic("a problem") } 輸出: (0x0,0x0) 2016/11/12 07:07:542016/11/12 07:07:54 a problem exit status 1
在日常開發(fā)過程中,經(jīng)常需要進(jìn)行調(diào)試,可以使用函數(shù)輸出完整的調(diào)用棧信息,比如:
func Myrecover(){ if err := recover(); err != nil{ fmt.Println(err) debug.PrintStack() //log.Fatalln(err) } } func main(){ defer Myrecover() panic("a problem") } 輸出: a problem goroutine 1 [running]: runtime/debug.Stack(0xc42002c010, 0xc42003fe20, 0x1) /root/data/go/src/runtime/debug/stack.go:24 +0x79 runtime/debug.PrintStack() /root/data/go/src/runtime/debug/stack.go:16 +0x22 main.Myrecover() /root/data/gopath/test/panic.go:10 +0x85 panic(0x48a5e0, 0xc42000a320) /root/data/go/src/runtime/panic.go:458 +0x243 main.main() /root/data/gopath/test/panic.go:16 +0x8d
日常開發(fā)中,只有在系統(tǒng)發(fā)生了不可恢復(fù)性或無法正常工作的錯誤可以使用panic,比如端口號被占用、數(shù)據(jù)庫未啟動、文件系統(tǒng)錯誤等,否則不建議使用。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。