日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何优化Golang中重复的错误处理

發布時間:2025/3/21 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何优化Golang中重复的错误处理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在看《Go入門指南》的一種用閉包處理錯誤的模式時,里面提到了一種錯誤的優雅處理方式,減少我們重復寫if err:=f(); err != nil{}式的代碼,感覺很心動,做了下測試,結論如下:

  • 能減少if err式的代碼,代碼可以變清新整潔。
  • 使用存在限制:只有當錯誤需要結束調用時才可以使用這種方法,如果被調用函數返回錯誤,但調用者函數需處理錯誤后,向下繼續執行,則不能采用這種方法。
  • 經常的寫法

    我們在設計函數時,錯誤處理要遵循以下2個規則:

  • 被調用函數如果有錯誤,需要傳遞給調用者,一定要返回
  • 調用者收到返回的錯誤,一定不可忽視,忽視就是埋bug。如果調用者不處理,被調函數就需要設計成無錯誤返回。
  • 我們都有這種感受,一個函數需要調用許多函數,然后處理他們的錯誤,光if err就寫了一堆,比如下面的test()函數。

    package main import ("errors""log" ) func main() {test() } func test() {if err := a(); err != nil {log.Println(err)}if err := b(); err != nil {log.Println(err)}if _, err := c(1, 0); err != nil {log.Println(err)}if _, err := d(1, 0); err != nil {log.Println(err)} } func a() error {return errors.New("error in a") } func b() error {return errors.New("error in b") } func c(x, y int) (int, error) {return x + y, errors.New("error in c") } func d(x, y int) (int, error) {if y == 0 {return 0, errors.New("error in d, divided by 0")}return x / y, nil }

      測試輸出:

      2018/10/24 14:42:40 error in a 2018/10/24 14:42:40 error in b 2018/10/24 14:42:40 error in c 2018/10/24 14:42:40 error in d, divided by 0
      • 優雅的方式

        借用2個小工具:

      • check函數,把錯誤轉化為panic
      • 函數在defer中增加錯誤處理,從panic中恢復錯誤,并打印
      • 我們對test()函數進行小小的改造。

        package main import ("errors""fmt" ) func main() {test() } func test() {defer func() {if r := recover(); r != nil {log.Println("got error: ", r)}}()var err errorerr = a()check(err)err = b()check(err)_, err = c(1, 2)check(err)_, err = d(1, 0)check(err) } func check(err error) {if err != nil {panic(err)} } func a() error {return errors.New("error in a") } func b() error {return errors.New("error in b") } func c(x, y int) (int, error) {return x + y, errors.New("error in c") } func d(x, y int) (int, error) {if y == 0 {return 0, errors.New("error in d, divided by 0")}return x / y, nil }

      輸出結果:

      2018/10/24 17:29:35 got error: error in a

      • test()函數是清爽了不少,也不用一直if然后處理err了,但是這種處理把錯誤轉化為panic,導致test()后續的代碼無法再繼續執行,b(), c(), d()幾個函數就沒法執行了。

        所以如果test()函數,遇到錯誤后就返回,就很適合這種優雅的方式。

        還可以更優雅嗎

        test()函數中的defer看著挺礙眼的,我們還能讓test()更簡潔點嗎,代碼再優雅點?

        采用文章中介紹的辦法,增加errorHandler()函數,實現對被調用函數的封裝,為它增加defer函數,恢復panic報的錯誤,看代碼。

        package main import ("errors""log" ) func main() {errorHandler(test)() } func test() {var err errorerr = a()check(err)err = b()check(err)_, err = c(1, 2)check(err)_, err = d(1, 0)check(err) } func check(err error) {if err != nil {panic(err)} } // 封裝f:為傳入的函數增加defer func errorHandler(f func()) func() {return func() {defer func() {if r := recover(); r != nil {log.Println("got error: ", r)}}()f()} } func a() error {return errors.New("error in a") } func b() error {return errors.New("error in b") } func c(x, y int) (int, error) {return x + y, errors.New("error in c") } func d(x, y int) (int, error) {if y == 0 {return 0, errors.New("error in d, divided by 0")}return x / y, nil }

      結果:

      2018/10/24 17:36:41 got error: error in a

      還能再一次優雅嗎

      errorHandler()函數不夠通用,它只接受無入參,無返回的函數。

    • 如果這篇文章對你有幫助,不妨關注下我的Github,有文章會收到通知。
    • 原文作者:大彬
    • 如果喜歡本文,隨意轉載,但請保留此原文鏈接:http://lessisbetter.site/2018/10/24/go-handle-error/
    • 總結

      以上是生活随笔為你收集整理的如何优化Golang中重复的错误处理的全部內容,希望文章能夠幫你解決所遇到的問題。

      如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。