先看一段代码,其中我们尝试用10 去除以0,编译是通过的,但是在运算时会报错
package main
import{
"fmt"
}
func test(){
num1 := 10
num2 := 0
res := num1 / num2 //错误,不能除以0
fmt.Println("res=",res)
}
func main(){
test()
fmt.Println("下面的代码和逻辑")
}
返回
panic: runtime error: integer divide by zero
错误处理机制
在默认情况下,当发生错误后(panic),程序就会退出(崩溃),为了保证程序的可靠性
我们希望当发生错误时,程序依然可以正常运行,并且可以在后续捕获到这个错误进行处理
说明
1. go语言不支持传统的try catch finally这种处理
2. go中引入的处理方式为. "defer","panic","recover"
3. Go中可以抛出一个panic的异常,然后在defer中通过recover捕获这个异常,然后正常处理
案例 使用defer + recover 来捕获和处理异常
package main
import "fmt"
func test(){
defer func() { //使用defer 延后操作,匿名函数会在下面代码块结束时触发
err := recover() //recover()内置函数,可以捕获到异常,捕获后程序正常运行
if err != nil { //判断是否有错误信息,
fmt.Println("err=",err) //如果有错误信息就打印出来
}
}()
num1 := 10
num2 := 0
res := num1 / num2 //错误程序
fmt.Println("res=",res)
}
func main(){
test()
fmt.Println("下面的代码和逻辑")
}
返回
err= runtime error: integer divide by zero
下面的代码和逻辑
//可以看到捕获到报错后,main中的println继续运行
自定义错误
go语言中,通过errors.New和panic 自定义错误类型
1. errors.New("错误说明") //会返回一个error类型的值,表示一个错误
2. panic //接收一个interface{}(空接口类型)类型的值(也就是任何值了)作为参数。
//可以接收error类型的变量,输出错误信息,并退出程序
案例
package main
import (
"errors"
"fmt"
)
func readConf(name string) error {
if name == "config.ini" { //判断传入的值是否对应config.ini
return nil //如果能够找到,说明是正确的。 返回值设置为nil 空,表示没有错误
}else{
return errors.New("读取文件错误") //当不匹配时,返回一个自定义的错误信息
//errors.New("") 创建一个error类型的数据,值为"读取文件错误"
}
}
func test2(){
err := readConf("config.ini") //随便定义一个值传参
if err != nil { //判断是否为nil,如果是说明程序正常
panic(err) //如果不是说明捕获到了错误
//这里将错误信息报出来 继续执行下面的语句
}
fmt.Println("test2继续执行")
//拷贝一份 传入一个不匹配的值
err1 := readConf("xxx")
if err1 != nil {
panic(err1) //判断不为空,说明有异常,报错终止程序
}
fmt.Println("test3继续执行")
}
func main(){
test2()
}
返回
test2继续执行
panic: 读取文件错误
//可以看到第二段报错的代码,panic的信息是我们自定义的报错信息