ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
Go语言的类型系统会在编译时捕获很多错误,但有些错误只能在运行时检查,如数组访问越界、空指针引用等。这些运行时错误会引起宕机。 一般而言,当发生宕机。程序会中断运行,并立即执行该goroutine(可以先理解成线程)中被延迟的函数(defer机制)。随后,程序崩溃并输出日志信息,日志信息包括panic value和函数调用的堆栈跟踪信息,panic value通常是某种错误信息。 虽然Go语言的panic机制类似于其他语言的异常。但panic的适用场景有一些不同,由于panic会引起程序的崩溃。因此panic一般用于严重错误,如程序内部的逻辑不一致。任何崩溃都表明了代码中可能存在漏洞,所以对于大部门漏洞,我们应该使用Go语言提供的错误机制,而不是panic。 ## 手动触发宕机 Go语言可以在程序中手动触发宕机,让程序崩溃,这样开发者可以及时地发现错误,同时减少可能的损失。 Go语言程序在宕机时,会将堆栈和 goroutine 信息输出到控制台,所以宕机也可以方便地知晓发生错误的位置,那么我们要如何触发宕机呢, 示例代码如下所示: ~~~ package main func main() { panic("crash") } ~~~ 代码运行崩溃并输出如下: ~~~ panic: crash goroutine 1 [running]: main.main() D:/code/main.go:4 +0x40 exit status 2 ~~~ ## 在运行依赖的必备资源缺失时主动触发宕机 regexp 是Go语言的正则表达式包,正则表达式需要编译后才能使用,而且编译必须是成功的,表示正则表达式可用。 编译正则表达式函数有两种,具体如下: #### 1) func Compile(expr string) (\*Regexp, error) 编译正则表达式,发生错误时返回编译错误同时返回 Regexp 为 nil,该函数适用于在编译错误时获得编译错误进行处理,同时继续后续执行的环境。 #### 2) func MustCompile(str string) \*Regexp 当编译正则表达式发生错误时,使用 panic 触发宕机,该函数适用于直接使用正则表达式而无须处理正则表达式错误的情况。 MustCompile 的代码如下: ~~~ func MustCompile(str string) *Regexp { regexp, error := Compile(str) if error != nil { panic(`regexp: Compile(` + quote(str) + `): ` + error.Error()) } return regexp } ~~~ ## 在宕机时触发延迟执行语句 当 panic() 触发的宕机发生时,panic() 后面的代码将不会被运行,但是在 panic() 函数前面已经运行过的 defer 语句依然会在宕机发生时发生作用,参考下面代码: ~~~ package main import "fmt" func main() { defer fmt.Println("宕机后要做的事情1") defer fmt.Println("宕机后要做的事情2") panic("宕机") } ~~~ 代码输出如下: ~~~ 宕机后要做的事情2 宕机后要做的事情1 panic: 宕机 goroutine 1 [running]: main.main() D:/code/main.go:8 +0xf8 exit status 2 ~~~