Go_error处理及panic、recover使用的正确姿势

2023年1月23日08:56:26

异常

异常就是程序出现了不正常的情况,会导致程序非正常停止,而异常处理就是针对非正常停止的情况,给出异常时的处理方式。语法错误不算异常体系中

error:

  • error是一个接口,作用是返回程序异常的信息,errors实现了error
  • 创建error使用errors.New()可以定义异常信息
  • 如果将error作为返回值的话,要放在返回值列表的最后

演示:

func TestError(num1, num2 int) (result int, err error) {
	err = nil
	if num1 == 0 || num2 == 0 {
		fmt.Println("除数不能为0")
		return
	}
	result = num1 / num2
	return
}

func main() {
	num, err := TestError(10, 1)
	if err != nil {
		err = errors.New("除数不能为0")
	} else {
		fmt.Println(num)
	}
}

标准库将error定义为接口类型,以便于实现自定义错误类型

type error interface { 
 Error() string 
}

error是最后一个返回参数。标准库提供了相关创建函数, 含简单错误文本的error对象

func main() {
	z, err := div(5, 0)
	if err == errDivByZero {
		log.Fatalln(err)
	}
	println(z)
}

var errDivByZero = errors.New("division by zero")

func div(x, y int) (int, error) {
	if y == 0 {
		return 0, errDivByZero
	}
	return x / y, nil
}

错误变量通常以err作为前缀,且字符串内容全部小写,没有结束标点,以便于嵌入到其他格式化字符串中输出。与errors.New类似的还有fmt.Errorf,它返回一个格式化内容的错误对象。某些时候,我们需要自定义错误类型,以便容纳更多上下文状态信息。如此,还可基于类型做出判断

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.Fatalln(err)
	}
	println(z)
}

type DivError struct {
	x, y int
}

//自定义错误类型。
func (DivError) Error() string {
	return "division by zero"
}

//实现error接口方法。
func div(x, y int) (int, error) {
	if y == 0 {
		return 0, DivError{x, y}
	}
	//返回自定义错误类型。
	return x / y, nil
}
  • 自定义错误类型通常以Error为后缀。在用switch按类型匹配时,注意case顺序。应将自定义类型放在前面,优先匹配具体错误类型
  • 在写代码中,我们不能忽略error返回值,应做严格检查,否则可能会导致错误的逻辑状态。调用多返回值函数时,除error外,其他返回值同样需要关注。以os.File.Read方法为例,它会同时返回剩余内容和EOF。

panic与recover:

panic是内置函数,可以终止程序,会立即中断当前函数流程,触发执行延迟调用
recover可以拦截panic异常信息,但是recover不可以直接调用,只有在defer调用的函数中有效

如果是放在循环中了,连续调用panic,仅最后一个会被recover捕耕

func main() {
	defer func() {
		if err := recover(); err != nil { // 捕捉错误
			log.Fatalln(err)
		}
	}()

	panic("我挂了")          // 引发错误
	fmt.Println("会走这一步吗") // 不会执行,编译器也会提示这是一个永远不会执行的代码
}

除非是不可恢复性,导致系统无法正常工作的错误,否则不建议使用Panic

例如:文件系统没有操作权限,服务端口被占用,数据库未启动等情况

  • 作者:itzhuzhu.
  • 原文链接:https://blog.csdn.net/weixin_45477086/article/details/122800934
    更新时间:2023年1月23日08:56:26 ,共 1676 字。