淺談Go語(yǔ)言的error類(lèi)型
error類(lèi)型是go語(yǔ)言的一種內(nèi)置類(lèi)型,使用的時(shí)候不用特定去import,他本質(zhì)上是一個(gè)接口
type error interface{ Error() string //Error()是每一個(gè)訂制的error對(duì)象需要填充的錯(cuò)誤消息,可以理解成是一個(gè)字段Error }
怎樣去理解這個(gè)訂制呢?
我們知道接口這個(gè)東西,必須擁有它的實(shí)現(xiàn)塊才能調(diào)用,放在這里就是說(shuō),Error()必須得到填充,才能使用.
比方說(shuō)下面三種方式:
第一種:通過(guò)errors包去訂制error
error := errors.New("hello,error")//使用errors必須import "errors"包 if error != nil { fmt.Print(err) }
來(lái)解釋一下errors包,只是一個(gè)為Error()填充的簡(jiǎn)易封裝,整個(gè)包的內(nèi)容,只有一個(gè)New方法,可以直接看
func New(text string) error
第二種:通過(guò)fmt.Errorf()去訂制
err := fmt.Errorf("hello error") if err != nil { fmt.Print(err) }
可以說(shuō)和第一種雷同了.
第三種:就是通過(guò)自定義的MyError塊去訂制了
//一個(gè)包裹了錯(cuò)誤類(lèi)型對(duì)象的自定義錯(cuò)誤類(lèi)型 type MyError struct { err error } //訂制Error() func (e MyError) Error() string { return e.err.Error() } func main() { err:=MyError{ errors.New("hello error"), } fmt.Println(err.Error()) }
三種方式差異都不大,輸出結(jié)果都是 hello error
實(shí)際上error只是一段錯(cuò)誤信息,真正拋出異常并不是單純靠error,panic和recover的用法以后總結(jié)。
補(bǔ)充:go error接口與errors包詳解
1 error接口
定義:
type error interface{ Error() string //Error()是一個(gè)方法,是每一個(gè)訂制的error對(duì)象需要填充的錯(cuò)誤消息,可以理解成是一個(gè)字段Error }
1.1 常見(jiàn)調(diào)用方式
模板
n, err := Foo(0) if err != nil { // 錯(cuò)誤處理 } else { // 使用返回值 n }
練習(xí)1
package main import ( "fmt" "os" ) func main() { f, err := os.Open("/test.txt") if err != nil { fmt.Println(err) return } fmt.Println(f.Name(), "opened successfully") }
[root@localhost error]# go run err3.go
open /test.txt: no such file or directory
1.2 自定義error方法
1.2.1 函數(shù)調(diào)用error
func Foo(param int)(n int, err error) { // ... }
1.2.2 自定義Error模板1
type fileError struct { } func (fe *fileError) Error() string { return "文件錯(cuò)誤" }
練習(xí)1
模擬一個(gè)錯(cuò)誤
package main import "fmt" type fileError struct { } func (fe *fileError) Error() string { //自定義會(huì)覆蓋原來(lái)的Error接口 return "文件錯(cuò)誤" } //只是模擬一個(gè)錯(cuò)誤 func openFile() ([]byte, error) { return nil, &fileError{} } func main() { conent, err := openFile() if err != nil { fmt.Println(err) } else { fmt.Println(string(conent)) } }
[root@localhost error]# go run err1.go
文件錯(cuò)誤
1.2 自定義Error模板2
自定義中添加一個(gè)字符串
type fileError struct { s string } func (fe *fileError) Error() string { return fe.s }
練習(xí)2
聲明fileError的時(shí)候,設(shè)置好要提示的錯(cuò)誤文字
package main import "fmt" type fileError struct { s string } func (fe *fileError) Error() string { return fe.s } //只是模擬一個(gè)錯(cuò)誤 func openFile() ([]byte, error) { return nil, &fileError{"文件錯(cuò)誤,自定義"} } func main() { conent, err := openFile() if err != nil { fmt.Println(err) } else { fmt.Println(string(conent)) } }
[root@localhost error]# go run err2.go
文件錯(cuò)誤,自定義
練習(xí)3
添加一個(gè)時(shí)間刻度
package main import ( "fmt" "time" ) type MyError struct { When time.Time What string } func (e MyError) Error() string { return fmt.Sprintf("%v: %v", e.When, e.What) } func oops() error { return MyError{ time.Date(1989, 3, 15, 22, 30, 0, 0, time.UTC), "the file system has gone away", } } func main() { if err := oops(); err != nil { fmt.Println(err) } }
[root@localhost error]# go run err4.go
1989-03-15 22:30:00 +0000 UTC: the file system has gone away
練習(xí)三
沒(méi)有打開(kāi)文件報(bào)錯(cuò)
package main import ( "fmt" "os" ) type PathError struct { Op string Path string Err error } func (e *PathError) Error() string { return e.Op + " " + e.Path + ": " + e.Err.Error() } func main() { f, err := os.Open("/test.txt") if errObject, ok := err.(*os.PathError); ok { fmt.Println("錯(cuò)誤輸出:",err, "文件路徑:", errObject.Path) return } fmt.Println(f.Name(), "opened successfully") }
[root@localhost error]# go run err5.go
錯(cuò)誤輸出: open /test.txt: no such file or directory 文件路徑: /test.txt
2 errors包
2.1 獲取error包
go get github.com/pkg/errors
2.2 errors.New()
errors.New()接收合適的錯(cuò)誤信息來(lái)創(chuàng)建
先聲明再使用
l練習(xí)1
package main import ( "errors" "fmt" ) var errNotFound error = errors.New("Not found error") func main() { fmt.Printf("error: %v", errNotFound) }
[root@localhost error]# go run errs1.go
error: Not found error
練習(xí)2
函數(shù)如何調(diào)用err
直接使用
package main import ( "errors" "fmt" ) func Sqrt(f float64) (float64, error) { if f < 0 { return 0, errors.New("math - square root of negative number") }else { return 1, errors.New("math - square root of 10") } } func main() { if _, err := Sqrt(-1); err != nil { fmt.Printf("Error: %s\n", err) } }
[root@localhost error]# go run errs2.go
Error: math - square root of negative number
3 自定義error與errors.New()使用比較
比較自定義error與errors.New()函數(shù)根據(jù)需求其實(shí)各有優(yōu)點(diǎn)。
package main import ( "errors" "fmt" ) type MsgError struct { Code int Msg string } func (msg *MsgError) Error() string { return fmt.Sprintf("%s", msg.Msg) } func f1(code int) (int, error) { if code == 1 { return -1, errors.New("msg test error") } return code, nil } func f2(code int) (int, error) { if code == 1 { return -1, &MsgError{code, "struct msg test error"} } return code, nil } func main() { for _, v := range []int{1, 2, 3, 4, 5, 6} { if code, err := f1(v); err != nil { fmt.Println(err) } else { fmt.Println("success:", code) } } for _, i := range []int{1, 2, 3} { if code, err := f2(i); err != nil { fmt.Println(err) } else { fmt.Println("success:", code) } } }
[root@localhost error]# go run errs3.go msg test error success: 2 success: 3 success: 4 success: 5 success: 6 struct msg test error success: 2 success: 3
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
- Go語(yǔ)言error的設(shè)計(jì)理念及背景演化詳解
- go語(yǔ)言?xún)?yōu)雅地處理error工具及技巧詳解
- GoFrame框架數(shù)據(jù)校驗(yàn)之校驗(yàn)結(jié)果Error接口對(duì)象
- go語(yǔ)言中切片Slice與數(shù)組Array對(duì)比以及panic:?runtime?error:?index?out?of?range問(wèn)題解決
- 一篇文章帶你輕松搞懂Golang的error處理
- Go?error的使用方式詳解
- golang常用庫(kù)之pkg/errors包第三方錯(cuò)誤處理包案例詳解
- Go語(yǔ)音開(kāi)發(fā)中常見(jiàn)Error類(lèi)型處理示例詳解
相關(guān)文章
大多數(shù)Go程序員都走過(guò)的坑盤(pán)點(diǎn)解析
這篇文章主要為大家介紹了大多數(shù)Go程序員都走過(guò)的坑盤(pán)點(diǎn)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12一文教你打造一個(gè)簡(jiǎn)易的Golang日志庫(kù)
這篇文章主要為大家詳細(xì)介紹了如何使用不超過(guò)130行的代碼,通過(guò)一系列g(shù)olang的特性,來(lái)打造一個(gè)簡(jiǎn)易的golang日志庫(kù),感興趣的小伙伴可以了解一下2023-06-06Golang實(shí)現(xiàn)Json轉(zhuǎn)結(jié)構(gòu)體的示例詳解
這篇文章主要為大家詳細(xì)介紹了Golang實(shí)現(xiàn)Json轉(zhuǎn)結(jié)構(gòu)體的方法,文中的示例代碼講解詳細(xì),對(duì)學(xué)習(xí)Go語(yǔ)言有一定的幫助,需要的可以參考一下2023-02-02Golang基礎(chǔ)教程之字符串string實(shí)例詳解
這篇文章主要給大家介紹了關(guān)于Golang基礎(chǔ)教程之字符串string的相關(guān)資料,需要的朋友可以參考下2022-07-07Golang?throttled基于GCRA速率限制庫(kù)使用探索
這篇文章主要為大家介紹了Golang?throttled基于GCRA速率限制庫(kù)使用實(shí)例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01一文理解Goland協(xié)程調(diào)度器scheduler的實(shí)現(xiàn)
本文主要介紹了Goland協(xié)程調(diào)度器scheduler的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06go語(yǔ)言實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的http文件服務(wù)器實(shí)例
這篇文章主要介紹了go語(yǔ)言實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的http文件服務(wù)器的方法,實(shí)例分析了Go語(yǔ)言操作http的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03