简单用法
代码实现
// Errors
package main
import (
"errors"
"fmt"
"log"
)
var errDivByZero = errors.New("division by zero") //定义全局的错误变量
func div(x, y int) (int, error) {
if 0 == y {
return 0, errDivByZero
}
return x / y, nil
}
func main() {
z, err := div(5, 0)
if err == errDivByZero {
log.Fatalln(err)
}
fmt.Println(z)
}
执行结果
# go run Errors.go
2018/02/27 11:39:30 division by zero
exit status 1
- 使用log.Fatalln(err)可导致程序返回状态为1,使用fmt输出则不会
自定义错误类型
代码实现
// CustomError
package main
import (
"fmt"
"log"
)
//自定义一个错误类型,也叫接口
type DivError struct {
x, y int
}
//实现errors.Error()接口方法
func (DivError) Error() string {
return "division by zero"
}
func div(x, y int) (int, error) {
if y == 0 {
return 0, DivError{x, y} //返回自定义错误类型,因为DivError实现了errors接口,所以可以直接返回
}
return x / y, nil
}
func main() {
z, err := div(5, 0)
if err != nil {
switch e := err.(type) {
case DivError:
fmt.Println(e, e.x, e.y)
default:
fmt.Println(e)
}
log.Fatal(err)
}
fmt.Println(z)
}
执行结果
# go run CustomError.go
division by zero 5 0
2018/02/27 14:05:48 division by zero
exit status 1
异常捕捉
简单的异常触发和捕捉
- 内置函数panic发起一个异常,立即中断当前函数流程,执行延迟调用
- 内置函数recover可捕获并返回panic提交的错误对象
代码实现
// Panic1
package main
import (
"fmt"
"log"
)
func main() {
defer func() {
if err := recover(); err != nil { //补捉错误
log.Fatal(err)
}
}()
panic("i am dead") //触发异常
fmt.Println("exit.") //永远不会执行
}
执行结果
# go run Panic1.go
2018/02/27 14:19:31 i am dead
exit status 1
错误中断沿调用栈向外传递
中断性错误沿调用栈传递,要么被外层捕捉,要么导致进程崩溃
代码实现
// Panic2
package main
import (
"fmt"
"log"
)
//函数内没有捕获异常,中断会继续向上抛
func test() {
defer fmt.Println("test1: i have not catch error")
defer fmt.Println("test2: i have not catch error")
panic("i am dead")
}
func main() {
defer func() {
log.Fatal(recover()) //异常中断在此处被捕获
}()
test()
}
执行结果
# go run Panic2.go
test2: i have not catch error
test1: i have not catch error
2018/02/27 14:34:46 i am dead
exit status 1
连续调用panic,仅最后一个会被recover捕获
代码实现
// Panic3
package main
import (
"log"
)
func main() {
defer func() {
for {
if err := recover(); err != nil { //只能捕获到最后一次异常
log.Println(err)
} else {
log.Fatalln("fatal")
}
}
}()
defer func() {
panic("yes, you are dead") //再次抛出异常
}()
panic("i am dead") //首次抛出异常
}
执行结果
# go run Panic3.go
2018/02/27 14:51:31 yes, you are dead
2018/02/27 14:51:31 fatal
exit status 1