精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Go Error 嵌套到底是怎么實現的?

開發 前端
error 是一個接口類型,只需要實現 Error() 方法即可。在 Error() 方法中,就可以返回自定義結構體的任意內容。

Go Error 的設計哲學是 「Errors Are Values」。

這句話應該怎么理解呢?翻譯起來挺難的。不過從源碼的角度來看,好像更容易理解其背后的含義。

Go Error 源碼很簡單,寥寥幾行:

  1. // src/builtin/builtin.go 
  2.  
  3. type error interface { 
  4.  Error() string 

error 是一個接口類型,只需要實現 Error() 方法即可。在 Error() 方法中,就可以返回自定義結構體的任意內容。

下面首先說說如何創建 error。

創建 Error

創建 error 有兩種方式,分別是:

  1. errors.New();
  2. fmt.Errorf()。

errors.New()

errors.New() 的使用延續了 Go 的一貫風格,New 一下就可以了。

舉一個例子:

  1. package main 
  2.  
  3. import ( 
  4.  "errors" 
  5.  "fmt" 
  6.  
  7. func main() { 
  8.  err := errors.New("這是 errors.New() 創建的錯誤"
  9.  fmt.Printf("err 錯誤類型:%T,錯誤為:%v\n", err, err) 
  10.  
  11. /* 輸出 
  12. err 錯誤類型:*errors.errorString,錯誤為:這是 errors.New() 創建的錯誤 
  13. */ 

這段代碼唯一讓人困惑的地方可能就是錯誤類型了,但沒關系。只要看一下源碼,就瞬間迎刃而解。

源碼如下:

  1. // src/errors/errors.go 
  2.  
  3. // New returns an error that formats as the given text. 
  4. // Each call to New returns a distinct error value even if the text is identical. 
  5. func New(text string) error { 
  6.  return &errorString{text} 
  7.  
  8. // errorString is a trivial implementation of error. 
  9. type errorString struct { 
  10.  s string 
  11.  
  12. func (e *errorString) Error() string { 
  13.  return e.s 

可以看到,errorString 是一個結構體,實現了 Error() 方法,New 函數直接返回 errorString 指針。

這種用法很簡單,但不實用。假如我還想返回程序的上下文信息,它就沒轍了。

下面看第二種方式。

fmt.Errorf()

還是先看一個例子:

  1. package main 
  2.  
  3. import ( 
  4.  "database/sql" 
  5.  "fmt" 
  6.  
  7. func foo() error { 
  8.  return sql.ErrNoRows 
  9.  
  10. func bar() error { 
  11.  return foo() 
  12.  
  13. func main() { 
  14.  err := bar() 
  15.  if err == sql.ErrNoRows { 
  16.   fmt.Printf("data not found, %+v\n", err) 
  17.   return 
  18.  } 
  19.  if err != nil { 
  20.   fmt.Println("Unknown error"
  21.  } 
  22.  
  23. /* 輸出 
  24. data not found, sql: no rows in result set 
  25. */ 

這個例子輸出了我們想要的結果,但是還不夠。

一般情況下,我們會通過使用 fmt.Errorf() 函數,附加上我們想添加的文本信息,使返回內容更明確,處理起來更靈活。

所以,foo() 函數會改成下面這樣:

  1. func foo() error { 
  2.    return fmt.Errorf("foo err, %v", sql.ErrNoRows) 

這時問題就出現了,經過 fmt.Errorf() 的封裝,原始 error 類型發生了改變,這就導致 err == sql.ErrNoRows 不再成立,返回信息變成了 Unknown error。

如果想根據返回的 error 類型做不同處理,就無法實現了。

因此,Go 1.13 為我們提供了 wrapError 來處理這個問題。

Wrap Error

看一個例子:

  1. package main 
  2.  
  3. import ( 
  4.  "fmt" 
  5.  
  6. type myError struct{} 
  7.  
  8. func (e myError) Error() string { 
  9.  return "Error happended" 
  10.  
  11. func main() { 
  12.  e1 := myError{} 
  13.  e2 := fmt.Errorf("E2: %w", e1) 
  14.  e3 := fmt.Errorf("E3: %w", e2) 
  15.  fmt.Println(e2) 
  16.  fmt.Println(e3) 
  17.  
  18. /* output 
  19. E2: Error happended 
  20. E3: E2: Error happended 
  21. */ 

乍一看好像好沒什么區別,但背后的實現原理卻并不相同。

Go 擴展了 fmt.Errorf() 函數,增加了一個 %w 標識符來創建 wrapError。

  1. // src/fmt/errors.go 
  2.  
  3. func Errorf(format string, a ...interface{}) error { 
  4.  p := newPrinter() 
  5.  p.wrapErrs = true 
  6.  p.doPrintf(format, a) 
  7.  s := string(p.buf) 
  8.  var err error 
  9.  if p.wrappedErr == nil { 
  10.   err = errors.New(s) 
  11.  } else { 
  12.   err = &wrapError{s, p.wrappedErr} 
  13.  } 
  14.  p.free() 
  15.  return err 

當使用 w% 時,函數會返回 &wrapError{s, p.wrappedErr},wrapError 結構體定義如下:

  1. // src/fmt/errors.go 
  2.  
  3. type wrapError struct { 
  4.  msg string 
  5.  err error 
  6.  
  7. func (e *wrapError) Error() string { 
  8.  return e.msg 
  9.  
  10. func (e *wrapError) Unwrap() error { 
  11.  return e.err 

實現了 Error() 方法,說明它是一個 error,而 Unwrap() 方法是為了獲取被封裝的 error。

  1. // src/errors/wrap.go 
  2.  
  3. func Unwrap(err error) error { 
  4.  u, ok := err.(interface { 
  5.   Unwrap() error 
  6.  }) 
  7.  if !ok { 
  8.   return nil 
  9.  } 
  10.  return u.Unwrap() 

它們之間的關系是這樣的:

圖片

因此,我們可以使用 w% 將上文中的程序進行改造,使其內容輸出更豐富。

如下:

  1. package main 
  2.  
  3. import ( 
  4.  "database/sql" 
  5.  "errors" 
  6.  "fmt" 
  7.  
  8. func bar() error { 
  9.  if err := foo(); err != nil { 
  10.   return fmt.Errorf("bar failed: %w", foo()) 
  11.  } 
  12.  return nil 
  13.  
  14. func foo() error { 
  15.  return fmt.Errorf("foo failed: %w", sql.ErrNoRows) 
  16.  
  17. func main() { 
  18.  err := bar() 
  19.  if errors.Is(err, sql.ErrNoRows) { 
  20.   fmt.Printf("data not found,  %+v\n", err) 
  21.   return 
  22.  } 
  23.  if err != nil { 
  24.   fmt.Println("Unknown error"
  25.  } 
  26.  
  27. /* output 
  28. data not found,  bar failed: foo failed: sql: no rows in result set 
  29. */ 

終于有了讓人滿意的輸出結果,每個函數都增加了必要的上下文信息,而且也符合對錯誤類型的判斷。

errors.Is() 函數用來判斷 err 以及其封裝的 error 鏈中是否包含目標類型。這也就解決了上文提出的無法判斷錯誤類型的問題。

后記

其實,Go 目前對 Error 的處理方式也是充滿爭議的。不過,官方團隊正在積極和社區交流,提出改進方法。相信在不久的將來,一定會找到更好的解決方案。

現階段來說,大部分團隊可能會選擇 github.com/pkg/errors 包來進行錯誤處理。如果感興趣的話,可以學學看。

 

責任編輯:姜華 來源: AlwaysBeta
相關推薦

2022-01-14 17:01:44

GoError結構

2016-11-17 22:18:31

id串行化服務器

2024-03-15 08:06:58

MySQLJOIN命令

2020-12-28 08:18:55

安全代碼線程

2024-05-11 09:41:45

線程安全代碼

2019-05-28 13:50:27

MySQL幻讀數據庫

2019-12-18 18:31:10

黑客醫療保險軟件

2023-07-14 12:21:29

流程@Autowired方法

2024-02-22 08:00:00

SoraOpenAI

2022-08-08 08:00:00

人工智能機器學習計算機應用

2023-10-12 08:54:20

Spring事務設置

2018-02-24 23:19:31

iOSbug蘋果

2024-12-09 09:55:25

2022-04-15 08:54:39

PythonAsync代碼

2022-05-24 17:00:41

區塊鏈IT比特幣

2025-10-29 07:33:13

2018-09-30 15:05:01

Linux用戶組命令

2015-04-21 09:20:40

SwfitObject—C

2025-10-31 00:00:02

硅光光通信英偉達

2022-04-10 19:26:07

TypeScript類型語法
點贊
收藏

51CTO技術棧公眾號

91久久精品国产91久久性色tv| 在线观看欧美日韩国产| 青青青青草视频| 亚洲av电影一区| 久久99热99| 7m精品福利视频导航| 国产一级淫片久久久片a级| 亚洲一区电影| 欧美三级一区二区| 国内少妇毛片视频| 邻居大乳一区二区三区| 国产一区二区影院| 日本不卡免费高清视频| 波多野结衣亚洲色图| 国产综合久久久| 日韩免费观看高清完整版在线观看| 凹凸日日摸日日碰夜夜爽1| av在线免费播放| 欧美激情一区二区三区四区| 国产麻豆乱码精品一区二区三区| 精品国产免费av| 天堂资源在线中文| 久久综合色婷婷| 99视频在线| 91片黄在线观看喷潮| 国产亚洲激情| 精品视频在线导航| 久久精品一卡二卡| 欧美日韩在线精品一区二区三区激情综合 | 欧美亚州在线观看| 成人午夜免费福利| 国产麻豆精品一区二区| 国产一区二区三区三区在线观看| 亚洲 欧美 日韩系列| 中国av在线播放| 日本va欧美va欧美va精品| 欧美高清激情视频| 成人免费毛片xxx| 日韩av久操| 欧美美女激情18p| 成人亚洲视频在线观看| 伊伊综合在线| 日韩欧美在线观看视频| 日本a级片在线播放| av在线免费播放| 亚洲精选免费视频| 国产av不卡一区二区| 色多多视频在线观看| 欧美激情一二三区| 日韩免费av电影| 成人在线免费电影| 国产精品色噜噜| 91在线视频一区| 夜夜狠狠擅视频| 麻豆国产精品一区二区三区 | 亚洲理论电影在线观看| 国精一区二区三区| 亚洲v日本v欧美v久久精品| 国产精品久久久久久久久久直播 | 久久亚洲黄色| 日韩电影中文字幕一区| 毛片一区二区三区四区| videos性欧美另类高清| 91久久香蕉国产日韩欧美9色| 日韩视频第二页| 精品成人av| 欧美男人的天堂一二区| 美女日批在线观看| 国产精品tv| 精品视频久久久| 四虎影视一区二区| 一区二区三区四区日韩| 亚洲精品久久久久国产| 三级电影在线看| 国产精品一国产精品| 日韩在线中文字| 欧美成人免费看| 99热免费精品| 国产精品网红福利| 精品人妻午夜一区二区三区四区| 国产精品久久久久久久久久妞妞 | 黄色一区二区视频| 激情伊人五月天久久综合| 99九九电视剧免费观看| 青春草在线观看| 国产一区久久久| 国产精品一区视频网站| 韩日在线视频| 亚洲精品国产一区二区精华液 | 欧美一级大片在线视频| 亚洲国产成人精品久久| 中文字幕av久久爽一区| 欧美二区不卡| 国产精品va在线| 亚洲欧美高清视频| 欧美国产欧美综合| 真人抽搐一进一出视频| 国产精品久久久久77777丨| 精品久久久久久久久久久久包黑料| 国产免费看av| 国内自拍一区| 国产一区二区在线免费视频| 日漫免费在线观看网站| 亚洲人成网站在线| 黄色三级视频片| 爱高潮www亚洲精品| 在线精品国产欧美| www.伊人久久| 国产超碰在线一区| 亚洲一卡二卡区| 亚洲精品日产| 日韩精品一区二区在线观看| 91麻豆制片厂| 国产精品久久久久久模特| 99精品在线直播| 日本免费视频在线观看| 色婷婷综合五月| 777米奇影视第四色| 欧美激情精品| 北条麻妃一区二区三区中文字幕| 国产精品久免费的黄网站| 成人午夜激情在线| 男同互操gay射视频在线看| 精品视频在线一区二区在线| 亚洲精品720p| 日本a在线观看| 国产日韩欧美| 国产精品我不卡| huan性巨大欧美| 欧美亚洲综合另类| 天堂在线中文在线| 欧美码中文字幕在线| 7777精品视频| 日韩一区二区三区在线观看视频| 一区二区在线观看免费| 99日在线视频| 91av精品| 91免费高清视频| 久久久久久国产精品免费无遮挡| 欧美日韩在线精品一区二区三区激情| 一道本在线观看| 久久久久99| 欧美久久电影| 黄色精品视频| 中文字幕日韩免费视频| 一区二区自拍偷拍| 中文字幕av在线一区二区三区| 波多野结衣天堂| 91麻豆精品| 久久精品国产91精品亚洲| 亚洲一区二区色| 亚洲人成影院在线观看| 少妇极品熟妇人妻无码| 黑丝一区二区三区| 久久久水蜜桃| 日韩色淫视频| 久久久www成人免费精品| 99久久精品国产一区色| 亚洲激情图片一区| 亚洲女则毛耸耸bbw| 亚洲国产专区校园欧美| 久久精品日韩精品| 日韩精品第一| 欧美成人亚洲成人日韩成人| 国产综合视频在线| 欧美性xxxxxx| 人妻熟人中文字幕一区二区| 激情图区综合网| 国产freexxxx性播放麻豆| 老司机aⅴ在线精品导航| 国产成人自拍视频在线观看| 亚洲国产精品久久久久久6q| 亚洲高清在线视频| 亚洲精品成人无码熟妇在线| 日本v片在线高清不卡在线观看| 丰满女人性猛交| 国产成人福利av| 国产精品mp4| 69成人在线| 亚洲精品一区在线观看香蕉| 中文字幕一区二区人妻| 亚洲欧美日韩久久| 极品白嫩的小少妇| 天堂精品中文字幕在线| 一区二区不卡在线观看| 国产精品网址| 国产精品欧美一区二区三区奶水 | 国产成人1区| 亚洲在线免费视频| 偷拍中文亚洲欧美动漫| 亚洲成人动漫在线播放| 中文字幕在线日本| 亚洲另类在线一区| 四虎永久免费在线观看| 国产一区二区三区在线看麻豆| 国产精品裸体瑜伽视频| 欧美日韩精品一区二区视频| 91社区国产高清| 玖玖在线播放| 久久精品国产久精国产思思| 国产精品国产高清国产| 制服丝袜国产精品| 天码人妻一区二区三区在线看 | 久久久久久久9| 三区四区不卡| 欧美另类网站| 国产一区丝袜| 亚洲wwwav| 国精产品一区二区三区有限公司 | 欧美网站免费| 欧洲中文字幕国产精品| 色a资源在线| 欧美一区二区视频在线观看| 亚洲区一区二区三| 久久亚洲欧美国产精品乐播| 免费在线观看日韩av| 九一九一国产精品| 久久精品免费网站| 性欧美xxxx大乳国产app| 久久久久久久香蕉| 国产精品久久久久无码av| 日本一区高清不卡| 天堂一区二区三区四区| 岛国视频一区免费观看| 高清不卡一区| 午夜精品理论片| 超碰在线观看免费| 日韩视频在线一区| 伊人在线视频| 中文字幕一区电影| 成人免费视频| 亚洲日本中文字幕免费在线不卡| 亚洲av片在线观看| 亚洲精品久久久久| 五月天婷婷视频| 日韩成人av一区| 天堂国产一区二区三区| 亚洲福利精品在线| 五月婷婷综合久久| 日韩国产精品一区| 日本v片在线免费观看| 亚洲精品国精品久久99热 | 中国一区二区视频| 日本韩国精品在线| 亚洲精品久久久久久久蜜桃| 日本精品免费观看高清观看| 五月婷婷六月婷婷| 在线免费观看视频一区| 国产精华7777777| 欧美无砖砖区免费| 国产精品九九九九| 日韩一区二区在线看片| 亚洲爱爱综合网| 亚洲第一视频网| 女人天堂在线| 色视频www在线播放国产成人| 欧美私人网站| 欧美成人免费观看| 国产传媒在线观看| 日韩av电影手机在线| 国产69精品久久| 91精品综合视频| 91精品啪在线观看国产手机| 久久久久网址| 欧美好骚综合网| 日韩a级黄色片| 午夜在线视频观看日韩17c| 亚洲激情在线观看视频| 国产一区二区三区精品欧美日韩一区二区三区 | 日韩一区二区欧美| 污污的视频在线观看| 午夜精品99久久免费| 九九热线视频只有这里最精品| 国产欧美最新羞羞视频在线观看| 老司机亚洲精品一区二区| 久久影视中文粉嫩av| 91久久夜色精品国产按摩| 国产视频在线观看网站| 先锋影音久久| 日本中文字幕观看| 99国产精品视频免费观看| 中文字幕在线观看二区| 亚洲国产视频网站| 啪啪小视频网站| 欧美va亚洲va在线观看蝴蝶网| 欧美色视频免费| 欧美成人激情视频| 欧美黑人疯狂性受xxxxx野外| 成人在线中文字幕| 西野翔中文久久精品字幕| 自拍亚洲欧美老师丝袜| 国产免费成人| 欧美成人手机在线视频| 91麻豆123| 欧美成人精品激情在线视频| 一本到三区不卡视频| 亚洲a视频在线| 一区二区亚洲精品国产| www在线看| 成人网欧美在线视频| 欧美激情在线精品一区二区三区| 久久久99精品视频| 蜜臀精品久久久久久蜜臀| 女女调教被c哭捆绑喷水百合| 国产视频一区不卡| 国产成人自拍视频在线| 欧美日本在线视频| 久草视频视频在线播放| 久久久久久久久久亚洲| aa亚洲一区一区三区| 日韩一区二区三区高清| 国产欧美日韩综合一区在线播放| 一级黄色片在线免费观看| 91美女视频网站| 日本在线免费观看| 日韩欧美一级二级| 91福利在线视频| 欧美一乱一性一交一视频| 国产精品宾馆| 强开小嫩苞一区二区三区网站 | 欧美精品亚洲一区二区在线播放| 免费成人av电影| 欧美一级片一区| 青青久久av| 人妻av中文系列| 不卡一区二区中文字幕| 久久久99精品| 欧美xxx久久| 日韩精品亚洲人成在线观看| 国产一区私人高清影院| 日韩成人三级| 黄色三级视频片| 国产日韩精品一区二区浪潮av | 亚洲国产欧美日本视频| 国偷自产av一区二区三区小尤奈| 欧美涩涩网站| 欧美图片自拍偷拍| 一二三区精品福利视频| 国产99久一区二区三区a片| 亚洲欧美精品在线| 一区二区乱码| 欧美大陆一区二区| 久久久久久9| 88久久精品无码一区二区毛片| 日韩欧美第一页| 飘雪影院手机免费高清版在线观看| 欧美在线视频一二三| 伊人久久大香线蕉无限次| 欧美 日韩精品| 国产视频911| 一级特黄aaa| 大胆人体色综合| 丁香婷婷成人| 欧美日韩黄色一级片| 久久久九九九九| 中文字幕久久熟女蜜桃| 日韩中文理论片| 亚洲一区网址| 久草资源站在线观看| 欧美国产成人在线| 国产精品久久久久久免费免熟| www.日韩.com| 成人偷拍自拍| 日韩中文字幕二区| 国产精品对白交换视频 | 国产91精品免费| 亚洲婷婷综合网| 久久激情视频久久| 粉嫩久久久久久久极品| 日日碰狠狠躁久久躁婷婷| 国产精品国模大尺度视频| 精品久久久久中文慕人妻| 韩国三级电影久久久久久| 国产影视一区| 亚洲av无码成人精品区| 色悠久久久久综合欧美99| 日本激情视频在线观看| 国产精品一区视频网站| 蜜臀久久99精品久久久久久9| 久久国产免费观看| 色综合天天天天做夜夜夜夜做| 福利小视频在线观看| 777午夜精品福利在线观看| 欧美日韩国产高清电影| 日本高清一区二区视频| 欧美日韩在线影院| 麻豆视频在线| 久久久精品动漫| 国产综合久久久久久久久久久久| 日韩欧美大片在线观看| 日韩中文在线观看| 欧美a级网站| 日韩av加勒比| 色婷婷国产精品久久包臀| aa在线视频| 日韩国产精品一区二区| 成人h精品动漫一区二区三区| 在线免费看91| 欧美一区二三区| 欧美激情综合|