GO语言提供了两种处理异常的方式
1.程序发生异常时,将异常信息反馈给使用者
2.程序发生异常时,立即退出终止程序运行
package main
import "fmt"
func main(){
//一、创建打印异常信息
1.通过fmt包中的errorf函数创建错误信息
var err1 error = fmt.Errorf("这里是错误信息")
2.通过errors包中的New函数创构错误信息
var err2 error = errors.New("这里也是错误信息")
fmt.Println(err1,err2)
//二、创建有异常的原理
//package builtin 定义了 error接口
//package errors 中提供了New方法,创建了实现error接口的结构体对象,并在创建时把指定的字符串传递给这个结构体
//fmt中的Errorf底层调用了errors包中的New函数
//三、应用
res,err := div(10,0) //调用方法
if(err!=nil){
fmt.Println(err) //除数不能为0
}else{
fmt.Println(res)
}
}
func div(a,b int)(res int,err error){ //返回值
if(b==0){
err = errors.New("除数不能为0")
}else{
res = a/b
}
return
}
中断程序
go语言提供了一个叫panic函数,用于发生异常时终止程序继续运行
package main
import "fmt"
func div(a,b int)(res int){
if(b==0){
//1.自定义触发panic终止程序
panic("除数不能为0")
}else{
res = a/b
}
return
}
func main(){
res : =div(10,0)
fmt.Println(res)
//2.自动触发panic
var arr = [3]int{1,3,5}
arr[5] = 666 //报错 角标越界 触发panic
//3.除非不可恢复,导致无法正常工作的错误,否则不建议使用panic
}
恢复程序
触发panic中断执行后,需要恢复程序,让程序继续之心,并且记录到底犯了什么错误
通过defer和recover来实现panic异常的捕获,让程序继续执行
package main
import "fmt"
func div(a,b int)(res int){
//定义一个延迟调用的函数,用于捕获panic异常
//注意:一定要在panic之前定义
defer func(){
if err := recover();err != nil{
res = -1
fmt.Println(err) //除数不能为0
}
}()
if(b==0){
panic("除数不能为0")
}else{
res = a/b
}
return
}
func setValue(arr []int,index int,value int){
arr[index] = value
}
func main(){
res := div(10,0)
fmt.Println(res) //-1
}
panic注意点
1.异常会沿调用堆栈向外传递,也可以在外层捕获
package main
import "fmt"
func div(a,b int)(res int){
if(b==0){
panic("除数不能为0")
}else{
res = a/b
}
return
}
func setValue(arr []int,index int,value int){
arr[index] = value
}
func main(){
//panic异常会沿着调用堆栈向外传递,所以可以在外层捕获
defer func(){
if err := recover();err != nil{
fmt.Println(err) //除数不能为0
}
}()
div(10,0)
}
2.多个异常只有第一个会被捕获
package main
import "fmt"
func test1(){
//多个异常,只有一个会被捕获
defer func(){
if err := recover() ; err!=nil{
fmt.Println(err)
}
}()
panic("异常a")
panic("异常b")
}
func main(){
test1(10,0)
}
3.异常写在defer中,那么只有defer中的异常会被捕获
package main
import "fmt"
func test2(){
//如果异常写在defer中,其他异常写在defer后面,那么只有defer中的异常会被捕获
defer func(){ //1
if err := recover(); err !=nil{
fmt.Println(err)
}
}()
defer func(){ //2
panic("异常B")
}()
panic("异常A") //3
}
func main(){
test1(10,0) //运行321 defer先进后出
}