網(wǎng)站首頁 編程語言 正文
概述
當(dāng)我們需要在Go項(xiàng)目中設(shè)計(jì)error,就不得不先知道Go error幾種常用方法。標(biāo)準(zhǔn)庫是一個非常好的學(xué)習(xí)方式,除此之外Go1.13的errors特性也需要掌握。
error使用方式
1.直接判等
這里的判等又分為變量判等和類型判等。
適用于pkg中預(yù)先定義好了多個error變量或類型,err只可能是這些變量的其中一個。
案例:os.IsExist(err)
// 變量判等 var errObj = errors.New(errObj) func IsErrObj(err error) bool { return err == errObj } // 類型判等 type PathError struct { Op string Path string Err error } func IsPathError(err error) bool { switch e := err.(type) { case *PathError: return true default: return false } }
2.組合error接口,構(gòu)建更強(qiáng)大的error接口
適用于構(gòu)造pkg級別專用的error接口類型,同時在struct中組合Err變量表示底層錯誤
案例:net.Error interface
package net type Error interface { error Timeout() bool // Is the error a timeout? Temporary() bool // Is the error temporary? } type AddrError struct { Err string Addr string }
3.Errno模式
我們知道Linux有大量的錯誤碼,表示了各種錯誤類型,對于很多系統(tǒng)而言錯誤碼非常好用。Go如何兼容這種errono模式呢?
案例:sysacall.Errno
type Errno uintptr func (e Errno) Error() string { if 0 <= int(e) && int(e) < len(errors) { s := errors[e] if s != "" { return s } } return "errno " + itoa.Itoa(int(e)) }
4.Go1.13的Wrap模式
在一些場景下,error是有鏈?zhǔn)疥P(guān)系的,我們固然可以自己實(shí)現(xiàn)一種鏈?zhǔn)絜rror類型,但是Go1.13引入了語言級別的支持。它非常簡單,只要3個重要的用法:
// 創(chuàng)建error err2 := fmt.Errorf("%w", err1) // 判斷error鏈條中是否包含某個err變量 ok := errors.Is(err2, err1) // true // 判斷error鏈條中是否可賦值為某個err類型,成功則賦值給target type Errno int func (e *Errno) Error() string { return strconv.Itoa(int(*e)) } func test() { var no = Errno(1) no1 := fmt.Errorf("%w", &no) no2 := fmt.Errorf("%w", no1) var target *Errno ok := errors.As(no2, target) fmt.Println(ok, target) // true, 1 }
以上代碼都依賴 errors.Unwrap 函數(shù),這個函數(shù)通過反射解析出鏈?zhǔn)絜rror的上一個error。
從代碼可以看出,error.Is 用于我們有2個err變量的情況下,判斷前者是否鏈接了后者;
error.As 用于我們有一個err變量和一種error類型,想要判斷鏈子中是否包含了這種error類型,如果是,我們順帶將值保存在target中,相當(dāng)于丟棄了一些鏈?zhǔn)降男畔ⅲ佃睔w真。 這里有2個注意點(diǎn):
- Unwrap依賴反射,我們知道Go的反射是很慢的,所以需要考慮性能的場景慎用
- As函數(shù)使用是,target本身必須是struct的指針類型,并且要取地址,否則可能會panic
5. Go版本低時的鏈?zhǔn)絜rror
有時候我們會看到 github.com/pkg/errors 這個包,它其實(shí)就是老版本Go想要使用鏈?zhǔn)絜rror所引用的包,它常用的方法是 Wrap 和 Cause,所以看到這2個函數(shù)就可以猜到一個項(xiàng)目沒有使用新的errors特性。
原文鏈接:https://juejin.cn/post/7102659941533483045
相關(guān)推薦
- 2022-06-25 關(guān)于Ubuntu?Server?18.04?LTS?安裝Tomcat并配置systemctl管理To
- 2022-04-17 idea中將項(xiàng)目打成jar包并在其他項(xiàng)目中引用
- 2022-10-30 Android?Studio調(diào)試Gradle插件詳情_Android
- 2022-07-11 Python內(nèi)建類型bytes深入理解_python
- 2022-08-02 Python?生成器yield原理及用法_python
- 2022-09-13 Python?迭代器介紹及作用詳情_python
- 2022-11-01 Python正則表達(dá)中re模塊的使用_python
- 2022-08-03 如何一鍵理清大型Python項(xiàng)目依賴樹_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- 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)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤: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)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支