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
~~~
- 1.Go语言前景
- 2.Go语言环境搭建
- 3.Go语言的基本语法
- 3.1变量
- 3.1.1变量声明
- 3.1.2变量初始化
- 3.1.3多个变量同时赋值
- 3.1.4匿名变量
- 3.1.5变量的作用域
- 3.1.6整型
- 3.1.7浮点类型
- 3.1.8复数
- 3.1.9bool类型
- 3.1.10字符串
- 3.1.11字符类型
- 3.1.12类型转换
- 3.2常量
- 3.1.1const关键字
- 3.2.2模拟枚举
- 4.Go语言的流程控制
- 4.2循环结构
- 4.3键值循环
- 4.4switch语句
- 4.5goto语句
- 4.6break语句
- 4.7continue语句
- 5.Go语言的函数
- 5.1函数声明
- 5.2函数变量
- 5.3函数类型实现接口
- 5.4闭包
- 5.5可变参数
- 5.6defer(延迟执行语句)
- 5.7处理运行时错误
- 5.8宕机(panic)
- 5.9宕机恢复(recover)
- 5.10Test功能测试函数
- 6.Go语言的内置容器
- 6.1数组
- 6.2切片
- 6.3map
- 6.4sync.Map
- 6.5list
- 6.6range
- 7.Go语言的结构体
- 8.Go语言的接口
- 9.Go语言的常用内置包
- 10.Go语言的并发
- 11.Go语言的文件I/O操作
- 12.Go语言的网络编程
- 13.Go语言的反射
- 14.Go语言的数据库编程
- 15.Go语言密码学算法
- 16.Go语言的gin框架
- 17.Go语言的网络爬虫
- 18.Go语言的编译和工具链