欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

error 基本概念

type error interface{
    Error() string
}

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

panic 和 recover

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

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

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

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

創(chuàng)建錯誤

// 方式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)建新錯誤。

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

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

// 方式4: 自定義錯誤類型
type MathCalError struct {
    message string
}
// 實現(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
}

處理錯誤

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

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

項目中使用 Error 的方案

方案一 :定義 ErrorMessage 包

項目中可以定義一個含有所有錯誤信息的包,然后在使用時直接引用。

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 處理不同類型的錯誤,
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)
  }
}

最后

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

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

相關(guān)文章

  • Go語言實現(xiàn)定時器的方法

    Go語言實現(xiàn)定時器的方法

    這篇文章主要介紹了Go語言實現(xiàn)定時器的方法,涉及Go語言時間操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • 關(guān)于Go你不得不知道的一些實用小技巧

    關(guān)于Go你不得不知道的一些實用小技巧

    開發(fā)語言上Go成為高并發(fā)業(yè)務(wù)開發(fā)的主流語言,再加上云原生技術(shù)底座的驅(qū)動,Go語言風光無限,下面這篇文章主要給大家介紹了關(guān)于Go你不得不知道的一些實用小技巧,需要的朋友可以參考下
    2022-11-11
  • Golang文件讀寫操作詳情

    Golang文件讀寫操作詳情

    這篇文章主要介紹了Golang文件讀寫操作詳情,文件是數(shù)據(jù)源(保存數(shù)據(jù)的地方)的一種,文件最主要的作用就是保存數(shù)據(jù),文件在程序中是以流的形式來操作的,更多詳細內(nèi)容需要的朋友可以參考一下
    2022-07-07
  • 關(guān)于golang中平行賦值淺析

    關(guān)于golang中平行賦值淺析

    這篇文章主要給大家介紹了關(guān)于golang中平行賦值的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用golang具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-08-08
  • Golang配置管理庫?Viper的教程詳解

    Golang配置管理庫?Viper的教程詳解

    這篇文章主要介紹了Golang?配置管理庫?Viper,使用?viper?能夠很好的去管理你的配置文件信息,比如數(shù)據(jù)庫的賬號密碼,服務(wù)器監(jiān)聽的端口,你可以通過更改配置文件去更改這些內(nèi)容,而不用定位到那一段代碼上去,提高了開發(fā)效率,需要的朋友可以參考下
    2022-05-05
  • gtoken替換jwt實現(xiàn)sso登錄的問題小結(jié)

    gtoken替換jwt實現(xiàn)sso登錄的問題小結(jié)

    這篇文章主要介紹了gtoken替換jwt實現(xiàn)sso登錄,主要介紹了替換jwt的原因分析及gtoken的優(yōu)勢,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • Go 自定義package包設(shè)置與導入操作

    Go 自定義package包設(shè)置與導入操作

    這篇文章主要介紹了Go 自定義package包設(shè)置與導入操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • Go使用Viper庫讀取YAML配置文件的示例代碼

    Go使用Viper庫讀取YAML配置文件的示例代碼

    Viper是適用于Go應(yīng)用程序的完整配置解決方案,它被設(shè)計用于在應(yīng)用程序中工作,并且可以處理所有類型的配置需求和格式,本文給大家介紹了Go使用Viper庫讀取YAML配置文件的方法,需要的朋友可以參考下
    2024-05-05
  • Go Excelize API源碼解讀GetSheetViewOptions與SetPageLayout

    Go Excelize API源碼解讀GetSheetViewOptions與SetPageLayo

    這篇文章主要為大家介紹了Go Excelize API源碼解讀GetSheetViewOptions與SetPageLayout方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • Golang中int類型和字符串類型相互轉(zhuǎn)換的實現(xiàn)方法

    Golang中int類型和字符串類型相互轉(zhuǎn)換的實現(xiàn)方法

    在日常開發(fā)中,經(jīng)常需要將數(shù)字轉(zhuǎn)換為字符串或者將字符串轉(zhuǎn)換為數(shù)字,在 Golang 中,有一些很簡便的方法可以實現(xiàn)這個功能,接下來就詳細講解一下如何實現(xiàn) int 類型和字符串類型之間的互相轉(zhuǎn)換,需要的朋友可以參考下
    2023-09-09

最新評論