我正在 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中文網其他相關文章!