最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang實(shí)踐之Error創(chuàng)建和處理詳解

 更新時(shí)間:2023年09月11日 10:18:48   作者:小雄Ya  
在 C#、Java 等語言中常常使用 try...catch的方式來捕獲異常,但是在Golang 對于錯(cuò)誤處理有不同的方式,像網(wǎng)上也有很多對 error 處理的最佳實(shí)踐的文章,其中很多其實(shí)就是對 error 的統(tǒng)一封裝,使用規(guī)范進(jìn)行約束,本文主要是記錄自己對處理 Error 的一些認(rèn)識和學(xué)習(xí)

error 基本概念

type error interface{
    Error() string
}

Golang 中 error類型是一個(gè)具有單個(gè)方法的接口,其內(nèi)置方法是返回描述錯(cuò)誤的字符串。Go 語言創(chuàng)始人覺得異常機(jī)制會(huì)導(dǎo)致控制流程混亂,降低代碼的可讀性,所以期望異常是一種可預(yù)知的。所以在使用時(shí)應(yīng)當(dāng)適當(dāng)?shù)姆祷?error ,然后調(diào)用方就可以更明確知道錯(cuò)誤,進(jìn)而再處理異常。同樣也說明了開發(fā)人員在 coding 時(shí)要能識別和預(yù)測可能發(fā)生錯(cuò)誤,再進(jìn)行處理,而不是忽略錯(cuò)誤,

panic 和 recover

但可能也會(huì)出現(xiàn)一些我們無法預(yù)料的錯(cuò)誤情況。比較嚴(yán)重的程序錯(cuò)誤導(dǎo)致發(fā)生 panic 就會(huì)使程序結(jié)束,所以它又提供一個(gè) recover 來捕獲 panic ,以便發(fā)生panic時(shí)能夠重新執(zhí)行啟動(dòng)程序。

defer func() {
        if r := recover(); r != nil {
            fmt.Println("重新啟動(dòng)程序:", r)
        }
}()

recover 函數(shù)最好在主函數(shù)中且必須在 defer 語句總使用,為了保證發(fā)生 panic 時(shí)被調(diào)用,如果沒有panic時(shí)recover 函數(shù)將會(huì)返回 nil。

對于panic 的錯(cuò)誤,應(yīng)當(dāng)全面記錄錯(cuò)誤信息,這樣才有利于排查問題。對于一些比較重要的服務(wù)應(yīng)當(dāng)適當(dāng)增加報(bào)警機(jī)制以通知相關(guān)團(tuán)隊(duì)或人員。

創(chuàng)建錯(cuò)誤

// 方式1:使用 fmt.Errorof("")
func div(x, y int)(int,error){
    if y==0 {
        return 0,fmt.Errorof("除數(shù) %d 不能為0",y)
    }
    return x/y, nil
}
// 方式2: 使用errors.New("")
ErrDivByZero := errors.New("除數(shù)不能為0")
return 0,ErrDivByZero
// 方式3:使用 errors.Wrap(err, "除數(shù)不能為0")
return 0,errors.Wrap(err, "除數(shù)不能為0")

方式1中 fmt.Errorf 函數(shù)允許使用格式化字符串創(chuàng)建新錯(cuò)誤。

errors.Wrap 函數(shù)允許使用上下文包裝error,使用場景:當(dāng)函數(shù)調(diào)用另一個(gè)方法時(shí)遇到的錯(cuò)誤而導(dǎo)致無法完成業(yè)務(wù)流程,那可能需要從函數(shù)返回錯(cuò)誤。使用 errors.Wrap 函數(shù)需要注意:因其除了錯(cuò)誤信息外還附加了堆棧信息,所以不能在程序中大量使用。

以上3種可以很簡單方便的創(chuàng)建錯(cuò)誤。當(dāng)然支持自定義錯(cuò)誤類型,通過創(chuàng)建實(shí)現(xiàn) error 接口的新類型。例如:

// 方式4: 自定義錯(cuò)誤類型
type MathCalError struct {
    message string
}
// 實(shí)現(xiàn) Error 方法
func (e *MathCalError) Error() string {
    return e.message
}
func div(x, y int) (int, error) {
    if y == 0 {
        return 0, &MathCalError{"除數(shù)不能為 0"}
    }
    return x / y, nil
}

處理錯(cuò)誤

根據(jù)遇到到場景,基本對于錯(cuò)誤的處理大致有下面五種情況:

  • 忽略錯(cuò)誤:調(diào)用方對于發(fā)生錯(cuò)誤覺得沒有任何影響,那么可以不接收直接忽略
  • 記錄錯(cuò)誤并繼續(xù)執(zhí)行:調(diào)用方覺得錯(cuò)誤無影響但需要進(jìn)行記錄,可以接受記錄
  • 傳遞錯(cuò)誤:繼續(xù)傳遞錯(cuò)誤。
  • 錯(cuò)誤重試:某功能錯(cuò)誤需要再重試,如請求第三方接口超時(shí)時(shí)想再重試。設(shè)置重試次數(shù)限制,以防止錯(cuò)誤持續(xù)存在時(shí)出現(xiàn)無限循環(huán)。
  • 嚴(yán)重錯(cuò)誤終止程序:若有些錯(cuò)誤期望終止程序,那直接 panic 處理。
// 忽略錯(cuò)誤
result,_ := getUser()
// 記錄錯(cuò)誤
result,err := getUser();err!=nil{
    log,writerInfo("something error", err.Error())
}
// 傳遞錯(cuò)誤
result,err := getUser();err!=nil{
   return err
}
// 錯(cuò)誤重試
retryCount := 0
 maxRetryCount := 3
for {
    result,err := getUser();
    if err!=nil{
       return err
       if retryCount >= maxRetryCount{
           return err
       } 
    }
    select {
    case <-ctx.Done():
     return ctx.Err()
    case <-time.After(time.Duration(retryCount) * time.Second):
     retryCount++
     continue
 }
}
//錯(cuò)誤后直接 panic
if err := getUser(); err != nil {
    panic("something wrong") 
}

項(xiàng)目中使用 Error 的方案

方案一 :定義 ErrorMessage 包

項(xiàng)目中可以定義一個(gè)含有所有錯(cuò)誤信息的包,然后在使用時(shí)直接引用。

package errorMsg
import "errors"
var UndefinedError = errors.New("未定義")
var InvalidateParamsError = errors.New("不合法參數(shù)")
// main 函數(shù)中使用
func getUser() error {
    return errorMsg.UndefinedError
}

方案二:自定義 error 類型

type ParamNotFound NotFound
type ValueNotFound NotFound
type NotFound struct {
	msg string
}
func (n *NotFound) Error() string {
	return n.msg
}
// 通過使用 switch 處理不同類型的錯(cuò)誤,
func handleErrors(err error) {
  switch v := err.(type) {
  case ParamNotFound:
    fmt.Printf("ParamNotFound: %v\n", v)
  case ValueNotFound:
    fmt.Printf("ValueNotFound: %v\n", v)
  default:
    fmt.Printf("Other error: %v\n", v)
  }
}

最后

有效的錯(cuò)誤處理對于構(gòu)建可靠的服務(wù)至關(guān)重要,個(gè)人覺得最佳的實(shí)踐是團(tuán)隊(duì)內(nèi)部的統(tǒng)一規(guī)范。沒有最佳實(shí)踐和方案,只有最適合的你的場景的實(shí)踐。

以上就是Golang實(shí)踐之Error創(chuàng)建和處理詳解的詳細(xì)內(nèi)容,更多關(guān)于Golang Error創(chuàng)建和處理的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go設(shè)計(jì)模式之原型模式圖文詳解

    Go設(shè)計(jì)模式之原型模式圖文詳解

    原型模式是一種創(chuàng)建型設(shè)計(jì)模式, 使你能夠復(fù)制已有對象, 而又無需使代碼依賴它們所屬的類,本文將通過圖片和文字讓大家可以詳細(xì)的了解Go的原型模式,感興趣的通過跟著小編一起來看看吧
    2023-07-07
  • 一文詳解go閉包(Closure)使用教程

    一文詳解go閉包(Closure)使用教程

    在Go語言中,閉包(Closure)是一種特殊的函數(shù),它可以捕獲其創(chuàng)建時(shí)所在作用域中的變量,本文給大家詳細(xì)介紹了go閉包(Closure)使用教程,感興趣的朋友可以參考下
    2024-01-01
  • Golang中SSE協(xié)議實(shí)現(xiàn)方法

    Golang中SSE協(xié)議實(shí)現(xiàn)方法

    Gin框架通過Server-SentEvents(SSE)實(shí)現(xiàn)流式返回,關(guān)鍵步驟包括設(shè)置正確的響應(yīng)頭、使用Flusher確保數(shù)據(jù)立即發(fā)送、處理客戶端中斷和錯(cuò)誤,本文給大家介紹Golang中SSE協(xié)議實(shí)現(xiàn)方法,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • go語言中的指針自動(dòng)解引用

    go語言中的指針自動(dòng)解引用

    Go語言中,編譯器會(huì)自動(dòng)解引用指針來訪問字段,自動(dòng)解引用使得使用指針訪問結(jié)構(gòu)體字段和方法變得更加直觀,降低了編程錯(cuò)誤的風(fēng)險(xiǎn),并使代碼更易于理解和維護(hù)
    2024-10-10
  • golang實(shí)現(xiàn)ping命令的完整代碼

    golang實(shí)現(xiàn)ping命令的完整代碼

    這篇文章給大家介紹了如何使用golang實(shí)現(xiàn)ping命令,文中給大家介紹了完整的實(shí)現(xiàn)代碼,并有詳細(xì)的圖文講解,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-02-02
  • Go語言開發(fā)發(fā)送Get和Post請求的示例

    Go語言開發(fā)發(fā)送Get和Post請求的示例

    這篇文章主要介紹了Go語言開發(fā)發(fā)送Get和Post請求的示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07
  • go?colly?爬蟲實(shí)現(xiàn)示例

    go?colly?爬蟲實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了go?colly?爬蟲實(shí)現(xiàn)示例,效果是根據(jù)輸入的瀏覽器cookie及excel必要行列號,從excel中讀取公司名稱,查詢公司法人及電話號碼。并寫回到excel中指定行
    2022-09-09
  • golang中之strconv包的具體使用方法

    golang中之strconv包的具體使用方法

    這篇文章主要介紹了golang中之strconv包的具體使用方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • Go語言中一定要知道的切片使用注意事項(xiàng)總結(jié)

    Go語言中一定要知道的切片使用注意事項(xiàng)總結(jié)

    了解和掌握切片的使用注意事項(xiàng),可以避免意外的程序行為,所以本文就來和大家深入探討一下Go語言切片常見的注意事項(xiàng),希望對大家有所幫助
    2023-06-06
  • golang簡單位運(yùn)算示例

    golang簡單位運(yùn)算示例

    這篇文章主要介紹了golang簡單位運(yùn)算,包括位移運(yùn)算、取反及位與位或等運(yùn)算,需要的朋友可以參考下
    2016-07-07

最新評論

绵阳市| 蒙阴县| 兴业县| 安陆市| 资兴市| 岳普湖县| 玛多县| 轮台县| 扶风县| 连城县| 沈丘县| 东乡县| 湖口县| 怀来县| 东乡族自治县| 故城县| 榆林市| 麻江县| 神农架林区| 北川| 砚山县| 吉林市| 黄平县| 台前县| 板桥市| 秭归县| 固原市| 会昌县| 剑河县| 乌恰县| 呼伦贝尔市| 原平市| 富宁县| 西和县| 乡宁县| 宝应县| 泰安市| 电白县| 南江县| 云阳县| 孟连|