Rumah >pembangunan bahagian belakang >Golang >Cara menangani ralat dalam golang
Golang biasanya mempunyai tiga kaedah pengendalian ralat: sentinel ralat (Ralat Sentinel), penegasan jenis ralat dan timbunan panggilan ralat rakaman. Sentinel ralat merujuk kepada menggunakan pembolehubah dengan nilai tertentu sebagai syarat penghakiman untuk cawangan pemprosesan ralat. Jenis ralat digunakan untuk menghalakan logik pengendalian ralat dan mempunyai kesan yang sama seperti pengawal ralat Sistem jenis menyediakan keunikan jenis ralat. Kotak hitam ralat merujuk kepada tidak terlalu memberi perhatian kepada jenis ralat dan mengembalikan ralat ke lapisan atas apabila tindakan perlu diambil, penegasan harus dibuat tentang tingkah laku ralat dan bukannya jenis ralat.
Persekitaran pengendalian tutorial ini: sistem Windows 7, GO versi 1.18, komputer Dell G3.
golang tidak menyediakan mekanisme pengendalian ralat yang serupa dengan try-catch
Ia menggunakan pengendalian ralat gaya bahasa C pada peringkat reka bentuk dan mengembalikan maklumat ralat melalui nilai pulangan fungsi
func ReturnError() (string, error) { return "", fmt.Errorf("Test Error") } func main() { val, err := ReturnError() if err != nil { panic(err) } fmt.Println(val) }Contoh di atas ialah contoh pengendalian ralat asas Timbunan panggilan yang dilaksanakan dalam persekitaran pengeluaran selalunya sangat kompleks, dan
yang dikembalikan juga selalunya diperlukan untuk menentukan pengendalian ralat tertentu berdasarkan maklumat ralat yang dikembalikan. error
di perpustakaan redis. gorm.RecordNotFounded
redis.NIL
Golang boleh membandingkan pembolehubah daripada jenis yang sama dan pembolehubah antara muka membandingkan alamat penuding yang ditunjukkan oleh antara muka. Oleh itu, jika dan hanya jika pembolehubah jenis
error
var ErrTest = errors.New("Test Error") err := doSomething() if err == ErrTest{ // TODO: Do With Error }
1 Struktur kod tidak fleksibel hanya boleh dinilai menggunakan
atau . Jika keadaan berterusan seperti ini, memudahkan anda menulis kod seperti spageti. ==
!=
var ErrTest1 = errors.New("ErrTest1") var ErrTest2 = errors.New("ErrTest1") var ErrTest3 = errors.New("ErrTest1") …… var ErrTestN = errors.New("ErrTestN") …… if err == ErrTest1{ …… } else if err == ErrTest2{ …… }else if err == ErrTest3{ …… } …… else err == ErrTestN{ …… }3 , Pembolehubah Sentinel akan membawa kepada gandingan yang sangat kuat, dan meludahkan ralat baharu dalam antara muka akan menyebabkan pengguna mengubah suai kod dengan sewajarnya dan mencipta ralat pemprosesan baharu.
type Error string func (e Error) Error() string { return string(e) }
Berbanding dengan penyelesaian di atas, Error Sentinel mempunyai penyelesaian yang lebih elegan yang bergantung pada antara muka dan bukannya pembolehubah:
var ErrTest1 = errors.New("ErrTest1") func IsErrTest1(err error) bool{ return err == ErrTest1 }Jenis ralat
type TestError { } func(err *TestError) Error() string{ return "Test Error" } if err, ok := err.(TestError); ok { //TODO 错误分支处理 } err := something() switch err := err.(type) { case nil: // call succeeded, nothing to do case *TestError: fmt.Println("error occurred on line:", err.Line) default: // unknown error }boleh digunakan untuk menyediakan strategi penghalaan yang elegan. Tetapi ini menjadikannya mustahil bagi pengguna untuk mengelakkan pergantungan yang berlebihan pada pakej.
switch
Menggunakan antara muka untuk membuang ralat yang lebih kompleks dan pelbagai masih memerlukan penukaran kod pemanggil.
func fn() error{ x, err := Foo() if err != nil { return err } } func main(){ err := fn() if IsTemporary(err){ fmt.Println("Temporary Error") } } type temporary interface { Temporary() bool } // IsTemporary returns true if err is temporary. func IsTemporary(err error) bool { te, ok := err.(temporary) return ok && te.Temporary() }Ringkasan
Adalah perlu untuk menambah ayat di sini,
Pemprosesan kotak hitam, mengembalikan ralat tidak bermakna mengabaikan kewujudan ralat atau mengabaikannya secara langsung, tetapi ia perlu ditangani dengan baik dalam tempat yang sesuai. Dalam proses ini, anda boleh menggunakan ralat's , ZapWrap
pengelogan, dsb. untuk merekodkan maklumat konteks pautan panggilan kerana ralat dikembalikan lapisan demi lapisan.
func authenticate() error{ return fmt.Errorf("authenticate") } func AuthenticateRequest() error { err := authenticate() // OR logger.Info("authenticate fail %v", err) if err != nil { return errors.Wrap(err, "AuthenticateRequest") } return nil } func main(){ err := AuthenticateRequest() fmt.Printf("%+v\n", err) fmt.Println("##########") fmt.Printf("%v\n", errors.Cause(err)) } // 打印信息 authenticate AuthenticateRequest main.AuthenticateRequest /Users/hekangle/MyPersonProject/go-pattern/main.go:17 main.main /Users/hekangle/MyPersonProject/go-pattern/main.go:23 runtime.main /usr/local/Cellar/go@1.13/1.13.12/libexec/src/runtime/proc.go:203 runtime.goexit /usr/local/Cellar/go@1.13/1.13.12/libexec/src/runtime/asm_amd64.s:1357 ########## authenticatePergi tutorial video
Atas ialah kandungan terperinci Cara menangani ralat dalam golang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!