GO语言小锤硬磕.十九 异常处理、中断程序、恢复程序

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先进后出
}

你可能感兴趣的:(go语言基础,golang,java,javascript)