首頁 > 後端開發 > Golang > 主體

Golang 中具體類型的錯誤片段

PHPz
發布: 2024-02-05 22:12:12
轉載
960 人瀏覽過

Golang 中具体类型的错误片段

問題內容

我正在 go 中嘗試錯誤包裝,並有一個返回包裝的自訂錯誤類型的函數。我想做的是迭代預期錯誤列表並測試函數的輸出是否包含這些預期錯誤。

我發現將自訂錯誤放入[]error 意味著自訂錯誤的類型將為*fmt.wraperror,這意味著errors.as( ) 幾乎總是回傳true。

作為範例,請考慮以下程式碼:

package main

import (
    "errors"
    "fmt"
)

type anothererror struct {
}

func (e *anothererror) error() string {
    return "another error"
}

type missingattrerror struct {
    missingattr string
}

func (e *missingattrerror) error() string {
    return fmt.sprintf("missing attribute: %s", e.missingattr)
}

func dosomething() error {
    e := &missingattrerror{missingattr: "key"}
    return fmt.errorf("dosomething(): %w", e)
}

func main() {
    err := dosomething()
    expectederrone := &missingattrerror{}
    expectederrtwo := &anothererror{}
    expectederrs := []error{expectederrone, expectederrtwo}

    fmt.printf("is err '%v' type '%t'?: %t\n", err, expectederrone, errors.as(err, &expectederrone))
    fmt.printf("is err '%v' type '%t'?: %t\n", err, expectederrtwo, errors.as(err, &expectederrtwo))

    for i := range expectederrs {
        fmt.printf("is err '%v' type '%t'?: %t\n", err, expectederrs[i], errors.as(err, &expectederrs[i]))

    }
}
登入後複製

其輸出為

is err 'dosomething(): missing attribute: key' type '*main.missingattrerror'?: true
is err 'dosomething(): missing attribute: key' type '*main.anothererror'?: false
is err 'dosomething(): missing attribute: key' type '*fmt.wraperror'?: true
is err 'dosomething(): missing attribute: key' type '*fmt.wraperror'?: true
登入後複製

理想情況下我希望輸出是

Is err 'DoSomething(): missing attribute: Key' type '*main.MissingAttrError'?: true
Is err 'DoSomething(): missing attribute: Key' type '*main.AnotherError'?: false
Is err 'DoSomething(): missing attribute: Key' type '*main.MissingAttrError'?: true
Is err 'DoSomething(): missing attribute: Key' type '*main.AnotherError'?: false
登入後複製

出現錯誤的原因是我希望能夠為每個測試案例條目定義預期錯誤的清單。假設我知道為函數提供某些輸入將使其沿著一條路徑返回包含特定錯誤的錯誤。

如何將 *fmt.wraperror 類型從 []error 切片轉換回原始類型,以便我可以將其與 error.as 一起使用?

我知道我可以使用 將其強制轉換為特定類型。 (anothererror),但為了在迭代切片時使其工作,我必須對函數可能返回的每個可能的錯誤執行此操作,不是嗎? )


正確答案


您可以使用以下方法欺騙 errors.as

func main() {
    err := DoSomething()
    m := &MissingAttrError{}
    a := &AnotherError{}
    expected := []any{&m, &a}

    for i := range expected {
        fmt.Printf("Is err '%v' type '%T'?: %t\n", err, expected[i], errors.As(err, expected[i]))
    }
}
登入後複製

列印的類型不是您所期望的,但 errors.as 按其應有的方式工作。

您的範例不起作用的原因是您傳遞給 errors.as 的是 *error。因此,包裝的錯誤值(即 err)被直接指派給目標值。在我的範例中,傳遞給 errors.as 的值是 **anothererror,並且 err 不能指派給 *anothererror

以上是Golang 中具體類型的錯誤片段的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板