Rumah > Artikel > pembangunan bahagian belakang > Apakah jenis ralat dalam bahasa Go?
Dalam bahasa Go, ralat ialah jenis antara muka. Jenis antara muka ralat ialah mod standard untuk pengendalian ralat Jika fungsi mengembalikan ralat, senarai jenis nilai pulangan mesti mengandungi ralat proses pemprosesan ralat adalah serupa dengan kod ralat dalam bahasa C, dan boleh dikembalikan lapisan demi lapisan sehingga ia diproses. Jenis antara muka ralat ditakrifkan sebagai rentetan Ralat() yang mengandungi hanya satu kaedah semua jenis yang melaksanakan antara muka ini boleh digunakan sebagai jenis ralat.
Persekitaran pengendalian tutorial ini: sistem Windows 7, GO versi 1.18, komputer Dell G3.
Ralat Go merujuk kepada mekanisme maklum balas manusia atau automatik yang disebabkan oleh situasi yang tidak konsisten dengan proses reka bentuk semasa pelaksanaan program. Sesetengah ralat direka bentuk secara sengaja, dan pengendalian ralat ditambah, atau maklum balas diberikan kepada pengguna untuk menunggu pemprosesan Contohnya, jika pembahagi ditandakan sebagai 0, ralat akan dilaporkan, supaya pengguna dapat mengenali masalah tersebut. daripada inputnya sendiri adalah untuk merangkak maklumat halaman yang ditentukan. Ralat lain adalah BUG yang disebabkan oleh pengaturcaraan yang lemah, seperti subskrip akses tatasusunan di luar sempadan, operasi penunjuk nol, dll. Pengendalian ralat yang direka dengan baik untuk pelbagai situasi adalah salah satu tanda kod matang, dan ia juga memerlukan pengalaman terkumpul atau reka bentuk yang teliti.
Jenis ralat bahasa Go
Ralat Go diwakili oleh ralat, iaitu jenis antara muka dan biasanya diisytiharkan bersama dengan nilai pulangan.
Pengendalian ralat adalah bahagian penting dalam setiap bahasa pengaturcaraan Biasanya, terdapat dua jenis pengecualian dan ralat yang dihadapi dalam pembangunan, dan bahasa Go tidak terkecuali.
Dalam bahasa C, ralat diwakili dengan mengembalikan maklumat seperti -1 atau NULL Walau bagaimanapun, bagi pengguna, jika mereka tidak menyemak dokumentasi API yang sepadan, mereka tidak akan dapat mengetahui nilai pulangan ini. mewakili. Maksudnya, sebagai contoh, mengembalikan 0 adalah kejayaan atau kegagalan?
Memandangkan situasi ini, jenis antara muka ralat diperkenalkan dalam bahasa Go sebagai mod standard untuk pengendalian ralat Jika fungsi mengembalikan ralat, senarai jenis nilai pulangan mesti mengandungi ralat. Proses pemprosesan ralat adalah serupa dengan kod ralat dalam bahasa C dan boleh dikembalikan lapisan demi lapisan sehingga ia diproses.
Jenis antara muka ralat ditakrifkan sebagai rentetan Ralat() yang mengandungi hanya satu kaedah. Semua jenis yang melaksanakan antara muka ini boleh dianggap sebagai jenis ralat. Kaedah Ralat() memberikan penerangan tentang ralat. Ini bermakna semua jenis data boleh dilengkapi dengan jenis ralat.
//The error built-in interface type is the conventional interface for representing an error condition, with the nil value representing no error. type error interface { Error() string }
//DNSError represents a DNS lookup error. type DNSError struct { Err string // description of the error Name string // name looked for Server string // server used IsTimeout bool // if true, timed out; not all timeouts set this IsTemporary bool // if true, error is temporary; not all errors set this; added in Go 1.6 } func (e *DNSError) Error() string func (e *DNSError) Temporary() bool //Temporary reports whether the DNS error is known to be temporary. This is not always known; a DNS lookup may fail due to a temporary error and return a DNSError for which Temporary returns false. func (e *DNSError) Timeout() bool //Timeout reports whether the DNS lookup is known to have timed out. This is not always known; a DNS lookup may fail due to a timeout and return a DNSError for which Timeout returns false.
Lihat secara khusus pada *DNSError untuk memahami definisi jenis ralat. * DNSError mengandungi 5 struktur medan. Err menerangkan teks ralat, Nama ialah nama domain pertanyaan, digunakan oleh pelayan Pelayan, dan IsTimeout dan IsTemporary ialah dua kuantiti Boolean yang menunjukkan punca ralat. Gunakan contoh berikut untuk memahami perkara ini secara terperinci.
func main() { name := "www.ilydsssss.com" addr, err := net.LookupHost(name) if errS, ok := err.(*net.DNSError); ok { fmt.Printf("%+v\n", *errS) fmt.Println(err) } else { fmt.Println(name, addr) } } /* result for ------www.ilydsssss.com------------ {Err:no such host Name:www.ilydsssss.com Server: IsTimeout:false IsTemporary:false} lookup www.ilydsssss.com: no such host ------------ www.iloveyou.com------------ {Err:getaddrinfow: This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server. Name:www.iloveyou.com Server: IsTimeout:false IsTemporary:false} lookup www.iloveyou.com: getaddrinfow: This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server. 传说中的发送DNS,没有返回的结果,原因你懂的, 这个是什么站点,noidea ----------- www.baidu.com ------------ www.baidu.com [180.97.33.108 180.97.33.107]
Dalam kes penggunaan di atas, jika pertanyaan gagal (iaitu, penunjuk tidak sifar), penegasan jenis dibuat Jika ia ialah *net.DNSError pointer, medan struktur adalah dicetak dan ralat dikeluarkan; jika tidak, ia dicetak Nama dan alamat domain. Dapat dilihat bahawa antara dua jenis ralat yang ditakrifkan, pertanyaan di atas tidak mengembalikan sebarang ralat, tetapi ia sememangnya ralat.
Pada masa yang sama, anda juga boleh meneka bahawa takrifan rentetan func (e *DNSError) Error() ialah return "look " + e.Name + e.Err.
Penciptaan ralat
Maklum balas ralat dalaman Go ditakrifkan dengan cara ini.
Tentukan struktur dan laksanakan antara muka ralat
Buat struktur baharu dan modelkan DNSError di atas untuk mencipta ralat yang perlu disimpan Struktur boleh direalisasikan dengan melaksanakan antara muka ralat pada masa yang sama.
error.New() fungsi
package errors // New returns an error that formats as the given text. func New(text string) error { return &errorString{text} } // errorString is a trivial implementation of error. type errorString struct { s string } func (e *errorString) Error() string { return e.s }
errorString ialah struktur yang mengandungi hanya satu jenis badan rentetan, dan juga melaksanakan antara muka ralat The New() hanya memulakan errorString dengan rentetan penerangan ralat dan mengembalikan alamat struktur Ini membolehkan jenis ralat mudah dipanggil terus pada bila-bila masa tanpa membuat struktur dan melaksanakan antara muka , jika perlu, gunakan kaedah 1.
Gunakan fmt.Errorf() untuk mengembalikan antara muka ralat
fmt.Errorf() tandatangan fungsi: func Errorf ( rentetan format, ralat ...antara muka{}), yang menggunakan rentetan terformat dan mengembalikan tandatangan menggunakan kaedah di atas. Adakah anda masih ingat bahawa fungsi Sprintf(rentetan format, rentetan ...antara muka{}), pelaksanaan fmt.Errorf() hanya mengembalikan ralat. Baharu(fmt.Sprintf(rentetan format, ...antara muka{}))
Ralat pengendalian
当写一个库时,如果发生一个错误,一种方式就是按照上述所说,抛出一个错误,由上层或用户去决断如何处理,是退出还是提示修改;另一种方式就是抛出 panic 来终止程序,除非遇到特别严重的错误,什么叫严重呢?就是程序已经没有执行的必要了,莫不如抛出错误,直接退出。有两种情况可以考虑使用 panic: 1. 发生了一个不能恢复的错误,此时程序不能继续运行。2. 存在一个编程上的错误。
当程序由 panic 引发终止时,可以使用 recover 重新获取该程序控制权。panic 和 recover 与其他语言中的 try-catch-finally 语句类似,只不过一般我们很少使用 panic 和 recover。
内建函数 panic 的签名为:func panic(interface{}),此处接口为空接口,也可以理解为任意数据类型都可以输入,输入什么,则提示什么。
func div(x, y int) float64 { defer fmt.Println("DIV ......") if y == 0 { panic(fmt.Sprintf("%d / %d, 除数为零, 无法计算", x, y)) } return float64(x) / float64(y) } fmt.Println(div(3, 0)) /* result panic: 3 / 0, 除数为零 goroutine 1 [running]: main.div(0x3, 0x0, 0x2) error.go:10 +0x148 main.main() error.go:25 +0x15a exit status 2 */
从上述例子可以看到,当函数发生 panic 时,它会终止运行,在执行完所有的延迟函数后,程序控制返回到该函数的调用方。这样的过程会一直持续下去,直到当前协程的所有函数都返回退出,然后程序会打印出 panic 信息,接着打印出堆栈跟踪,最后程序终止。
recover 是一个内建函数,用于重新获得 panic 协程的控制。recover 函数的标签如下所示:func recover() interface{}。需要注意的是:只有在延迟函数的内部,调用 recover 才有用。在延迟函数内调用 recover,可以取到 panic 的错误信息,并且停止 panic 续发事件,程序运行恢复正常。如果在延迟函数的外部调用 recover,就不能停止 panic 续发事件。
例如:
import ( "runtime/debug" ) func recoverFdiv() { if r := recover(); r != nil { fmt.Println("来自 DIV 的恢复, 除数为零,下面是出错log记录") debug.PrintStack() } } func div(x, y int) float64 { defer recoverFdiv() if y == 0 { panic(fmt.Sprintf("%d / %d, 除数为零, 无法计算", x, y)) } return float64(x) / float64(y) } fmt.Println(div(3, 0)) /* result 来自 DIV 的恢复, 除数为零,下面是出错log记录 goroutine 1 [running]: runtime/debug.Stack(0xc000072008, 0xc00006fd68, 0x1) runtime/debug/stack.go:24 +0xae runtime/debug.PrintStack() runtime/debug/stack.go:16 +0x29 main.recoverFdiv() D:/ZHY-L/OneDrive/文档/开发/goblog/myerror.go:12 +0x89 panic(0x4b9620, 0xc000030040) runtime/panic.go:513 +0x1c7 main.div(0x3, 0x0, 0x0) error.go:19 +0x186 main.main() error.go:34 +0x15a 0 */
如上所示,调用延迟函数 recoverFdiv(),它使用了 recover() 来停止 panic 续发事件,主函数还是继续执行了。同时,利用debug.PrintStack() 打印了 panic 记录,这样在保证程序继续执行的同时,也留下了调试宝贵的记录。
同理,Go 内置的运行时错误(如数组越界)也会导致 panic。这等价于调用了内置函数 panic,其参数由接口类型 runtime.Error 给出。runtime.Error 接口的定义如下:
type Error interface { error // RuntimeError is a no-op function but // serves to distinguish types that are run time // errors from ordinary errors: a type is a // run time error if it has a RuntimeError method. RuntimeError() }
Atas ialah kandungan terperinci Apakah jenis ralat dalam bahasa Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!