错误处理
2022-02-24 大约 2 分钟
错误处理在程序中是必然的问题,因为错误会打断程序的正常执行。在Go语言中为了追求代码优雅,引入defer+recover机制处理错误。
# defer+recover
处理错误
recover:
func recover() interface{}
1
内建函数recover允许程序管理恐慌过程中的Go程。在defer的函数中,执行recover调用会取回传至panic调用的错误值,恢复正常执行,停止恐慌过程。若recover在defer的函数之外被调用,它将不会停止恐慌过程序列。在此情况下,或当该Go程不在恐慌过程中时,或提供给panic的实参为nil时,recover就会返回nil。
看下面一段代码,10/0 实际会报出错误,程序会被中断,无法继续执行。
package main
import "fmt"
func main() {
test()
fmt.Println("上面的除法操作执行成功")
}
func test() {
num1 := 10
num2 := 0
result := num1 / num2
fmt.Println(result)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
panic: runtime error: integer divide by zero
goroutine 1 [running]:
main.test()
E:/goProject/src/goCode/testProject01/unit2/main/main.go:15 +0x11
main.main()
E:/goProject/src/goCode/testProject01/unit2/main/main.go:8 +0x19
Process finished with the exit code 2
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
错误处理:
package main
import "fmt"
func main() {
test()
fmt.Println("上面的除法操作执行成功")
}
func test() {
defer func() {
// 利用recover内置函数,可以捕获错误
err := recover()
// 如果没有捕获错误,返回值为零值:nil
if err != nil {
fmt.Println("错误已经捕获")
fmt.Println("err是:", err)
}
}()
num1 := 10
num2 := 0
result := num1 / num2
fmt.Println(result)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
错误已经捕获
err是: runtime error: integer divide by zero
上面的除法操作执行成功
Process finished with the exit code 0
1
2
3
4
5
2
3
4
5
通过错误处理我们可以提高程序的健壮性。
# 自定义错误
需要调用errors包下的New函数
语法:
func New(text string) error
1
使用字符串创建一个错误,请类比fmt包的Errorf方法,差不多可以认为是New(fmt.Sprintf(...))。
package main
import (
"errors"
"fmt"
)
func main() {
err := test()
if err != nil {
fmt.Println("自定义错误:", err)
}
fmt.Println("上面的除法操作执行成功")
}
func test() (err error) {
num1 := 10
num2 := 0
if num2 == 0 {
// 抛出自定义错误
return errors.New("除数不能为0哦")
} else {
result := num1 / num2
fmt.Println(result)
return nil
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
有一种情况:程序出现错误以后,后续代码就没有必要执行,想让程序中断,退出程序,借助builtin包下的内置函数:panic
func main() {
err := test()
if err != nil {
fmt.Println("自定义错误:", err)
// 终止代码继续执行
panic(err)
}
fmt.Println("上面的除法操作执行成功")
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9