先看一段代码,其中我们尝试用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的信息是我们自定义的报错信息