Banyak pembangun mengesyorkan membungkus ralat dalam Go menggunakan fmt.Errorf dengan kata kerja %w, tetapi ini kaedah tidak menyediakan pembalut rekursif sebenar. Untuk menyemak ralat secara rekursif menggunakan Is() dan As(), jenis ralat tersuai boleh digunakan.
Berikut ialah Ralat jenis ralat tersuai yang menyokong pembungkusan ralat dan semakan rekursif :
type errorChain struct { err error next *errorChain } func Wrap(errs ...error) error { out := errorChain{err: errs[0]} n := &out for _, err := range errs[1:] { n.next = &errorChain{err: err} n = n.next } return out }
Kunci untuk mendayakan semakan rekursif adalah dengan melaksanakan kedua-dua kaedah Is() dan As() pada jenis tersuai. Kaedah ini membenarkan perbandingan ralat pada ralat yang terkandung dalam rantai, dan bukannya rantai itu sendiri:
func (c errorChain) Is(err error) bool { return errors.Is(c.err, err) } func (c errorChain) As(target any) bool { return errors.As(c.err, target) }
Dengan kaedah ini disediakan, anda boleh membalut ralat dan melakukan semakan rekursif :
errs := Wrap(errors.New("error 0"), errors.New("error 1"), errors.New("error 2")) fmt.Println(errors.Is(errs, errors.New("error 0"))) // true fmt.Println(errors.Is(errs, errors.New("error 1"))) // true fmt.Println(errors.Is(errs, errors.New("error 2"))) // true
The Kaedah Unwrap() dalam errorChain membolehkan anda melintasi ralat yang dibalut dalam rantai:
var currentError error = errs for { currentError = errors.Unwrap(currentError) if currentError == nil { break } fmt.Println(currentError) }
Contoh ini mencetak semua ralat dalam rantai:
error 0 error 1 error 2
Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Mencapai Ralat Rekursif Benar Membungkus dan Membuka Balutan dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!