文章目录
异常处理
Golang中引入error接口类型作为错误处理的标准模式,如果函数要返回错误,则返回值类型列表中肯定包含error。error处理过程类似于C语言中的错误码,可逐层返回,直到被处理。
Golang中引入两个内置函数panic和recover来触发和终止异常处理流程,同时引入关键字defer来延迟执行defer后面的函数。
一直等到包含defer语句的函数执行完毕时,延迟函数(defer后的函数)才会被执行,而不管包含defer语句的函数是通过return的正常结束,还是由于panic导致的异常结束。
1.error接口
1.1 error接口的定义
type error interface {
Error() string
}
1.2 生成error值的方法
1.2.1 使用errors包的New函数
- errors包的源码
package errors
//errors
type errorString struct {
text string
}
func New(text string) error { //New()
return &errorString{text}
}
func (e *errorString) Error() string {
return e.text
}
- errors包的使用
package main
import (
"errors"
"fmt"
)
func main() {
var err error = errors.New("It’s a normal err.")
fmt.Println(err)
}
1.2.2 调用fmt包中的Errorf函数
- Errorf源码
package fmt
import "errors"
func Errorf(format string, args ...interface{}) error {
return errors.New(Sprintf(format, args...)) //根据fomat参数生成格式化的字符串并返回
}
- Errorf的使用
package main
import "fmt"
func main() {
var err = fmt.Errorf("%s", " It’s a normal err")
fmt.Println(err)
}
2. panic
- a.向程序使用方报告普通的错误状态的方式是返回一个额外的error类型值
- b.当遇到不可恢复的错误状态的时候,如数组访问越界、空指针引用等,通过调用panic作为报告致命错误的一种方式。
package main
import "fmt"
func testA() {
fmt.Println("func testA()")
}
func testB(x int) {
var a [10]int
a[x] = 222 //x值为10时,数组越界
}
func testC() {
fmt.Println("func testC()")
}
func main() {
testA()
testB(10) //testB()
testC()
}
运行结果,发生panic错误
func testA()
panic: runtime error: index out of range
goroutine 1 [running]:
main.testB(...)
/home/rui/GO/src/GolangDemo/test.go:10
main.main()
/home/rui/GO/src/GolangDemo/test.go:17 +0x25
3.recover
func recover() interface{}
- a. 程序运行时出现panic异常就会导致程序奔溃,Go语言提供了专用与”捕获“运行时panic的内建函数——recover。它可以是当前的程序从运行时panic状态中恢复,并重新获得流程控制权。
- b. recover只有在defer调用的函数(自定义函数和匿名函数)中有效
- c. 当主程序有多个panic,recover能够捕获第一个错误;当延迟调用函数中有panic,捕获最后一个错误。
package main
import "fmt"
func testA() {
fmt.Println("func testA()")
}
func testB(x int) {
var a [10]int
a[x] = 222 //x值为10时,数组越界
}
func testC() {
fmt.Println("func testC()")
}
func main() {
defer func() {
fmt.Println(recover())
}()
testA()
testB(10) //runtime error: index out of range
testC()
}
运行结果,捕获到异常信息:
func testA()
runtime error: index out of range
如果我们在开发中,遇到需要抛出的异常也可以直接使用panic,类似与其c++和java的 throw。
当多个defer中都有panic的时候,捕获最后一个panic。
package main
import "fmt"
func main() {
defer func() {
fmt.Println(recover())
}()
defer func() {
panic("defer panic")
}()
panic("test panic")
}