簡體   English   中英

了解在 GoLang 中處理返回的指針和錯誤檢查的最佳實踐

[英]Understanding best practices for handling returned pointers in GoLang and error checking

假設我有以下 function

func GetNumber() (*int, error) {
   numb, err := getNumberFromDB(db)
   if err != nil {
       return nil, errors.New("error from db")
   }
   return numb, nil
}

numb 是一個*int ,但它作為 nil 返回的唯一情況是,如果有錯誤

因此,如果我正在使用GetNumber() ,我是否還應該在使用之前檢查 int 是否為 nil ? 感覺我應該防止將來對GetNumber的更改導致問題(或者可能 getNumberFromDB 在某些時候出於某種原因開始不返回錯誤)。

但我也覺得它非常多余,我到處添加這些條件檢查。 只是想確保我沒有遵循最佳實踐。

IE:

numb, err : = GetNumber()
if err != nil {
    //handle error
}
if numb == nil {
   // this shouldn't happen
}

另一個例子:

func EmailFromContext(ctx context.Context, key interface{}) (*string, error) {
    ctxVal, ok := ctx.Value(key).(*validator.ValidatedClaims)
    if !ok {
        // so should this be returning "" instead of nil?
        return nil, errors.New("could not convert claims")
    }
    return &claims.Email, nil
}

不知道getNumberFromDB()的實現或底層架構,可能會找到一條記錄,但表中的字段具有NULL值。 在這種情況下, getNumberFromDB有可能返回nil, nil (沒有數字,沒有錯誤)。 在這種情況下,您仍然需要檢查nil ,即使沒有返回錯誤。 但是,我會將該檢查移至GetNumber function,而不是返回指向整數的指針。 他們大部分時間都是 PITA,尤其是在處理並發時。 我會寫這樣的東西:

func GetNumber() (int, error) {
    i, err := getNumberFromDB()
    if err != nil {
        return 0, err // perhaps wrap the DB error
    }
    if i == nil {
        return 0, ErrNumberNotSet // pre-defined error variable
    }
    return *i, nil // return value
}

有了這個 function,你可以這樣做:

i, err := GetNumber()
if err != nil {
    // handle error
}
fmt.Sprintf("Got number %d from DB\n", i)

此外,您可以稍微更改GetNumber function 以設置 NULL 值的默認值:

func GetNumber(def int) (int, error) {
    i, err := getNumberFromDB()
    if err != nil {
        return 0, err // perhaps wrap the DB error
    }
    if i == nil {
        return def, nil
    }
    return *i, nil // return value
}

在這種情況下:

num, err := GetNumber(123)
if err != nil {
    // handle DB error
}
fmt.Printf("Number is: %d\n", num)

一般來說,非零錯誤意味着其他結果是沒有意義的。 然而,這並不是每個人都嚴格遵守的。 例如,如果您正在編寫 gRPC 服務器,則不應期望返回帶有非 nil 錯誤的非 nil 值。 而在標准庫中, io.Reader返回讀取的字節數和io.EOF

所以有幾個選項,所有這些都可以工作:

您可以假設零錯誤意味着有意義的結果。 在這種情況下,您必須定義什么是有意義的結果。 根據您的描述,它看起來不能為 nil,因此可以不檢查 nil。

如果 function 不能返回 nil,那么不返回指針可能是有意義的,除非有理由讓它成為指針。

但是,在許多情況下,返回 nil,nil 可能是有意義的。

我的建議是返回 (int,error),除非有其他理由返回指針。 這將簡化調用者對 function 的使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM