Go语言学习笔记(十五)之异常处理

22.异常处理

error接口定义如下:

  1: type error interface {
  2: 	Error() string
  3: }

Go语言的标准库代码包errors为用户提供如下方法:

  1: package errors
  2: 
  3: type errorString struct {
  4: 	text string
  5: }
  6: 
  7: func New(text string) error {
  8: 	return &errorString{text}
  9: }
 10: 
 11: func (e *errorString) Error() string {
 12: 	return e.text
 13: }

另一个可以生成error类型值的方法是调用fmt包中的Errorf函数:

  1: package fmt
  2: import "errors"
  3: 
  4: func Errorf(format string, args ...interface{}) error{
  5: 	return errors.New(Sprintf(format,args...))
  6: }
  7: 

简单代码示例:

  1: package main
  2: import (
  3: 	"errors"
  4: 	"fmt"
  5: )
  6: 
  7: func main() {
  8: 	var errl error = errors.New("a normal errl")
  9: 	fmt.Println(errl)
 10: 
 11: 	var err2 error = fmt.Errorf("%s", "a normal err2")
 12: 	fmt.Println(err2)
 13: }

error接口的应用

  1: package main
  2: import "fmt"
  3: import "errors"
  4: 
  5: func MyDiv(a, b int) (result int, err error){
  6: 	err = nil
  7: 	if b == 0 {
  8: 		err = errors.New("被除数不能为0")
  9: 	}else {
 10: 		result = a/b
 11: 	}
 12: 	return
 13: }
 14: 
 15: func main() {
 16: 	result, err := MyDiv(8, 0)
 17: 	if err != nil{
 18: 		fmt.Println("err=", err)
 19: 	} else {
 20: 		fmt.Println("result=", result)
 21: 	}
 22: }

panic函数

某些不应该发生的场景发生时,我们就应该调用panic。当panic异常发生时,程序会中断运行,并立即执行在该goroutine。随后程序崩溃并输出日志信息。日志信息包括panic 。value的函数调用的堆栈跟踪信息。

panic函数接受任何值作为参数

  1: func panic(v interface{})

调用panic函数引发的panic异常

  1: func TestA() {
  2: 	fmt.Println("func TestA{}")	
  3: }
  4: func TestB() {
  5: 	panic("func TestB():panic")
  6: }
  7: 
  8: func TestC() {
  9: 	fmt.Println("func TestC()")
 10: }
 11: 
 12: func main() {
 13: 	TestA()
 14: 	TestB() //发生异常,中断程序
 15: 	TestC()
 16: }
  1: >>> func TestA{}
  2: panic: func TestB():panic

数组越界会自动调用panic

  1: func TestA() {
  2: 	fmt.Println("func TestA{}")	
  3: }
  4: func TestB(x int) {
  5: 	var a [10]int
  6: 	a[x] = 111
  7: }
  8: 
  9: func TestC() {
 10: 	fmt.Println("func TestC()")
 11: }
 12: 
 13: func main() {
 14: 	TestA()
 15: 	TestB(20) //发生异常,中断程序
 16: 	TestC()
 17: }
  1: >>> func TestA{}
  2: panic: runtime error: index out of range

recover函数的使用

panic异常会导致程序崩溃。而recover函数专门用于“拦截”运行时的panic异常,它可以是当前程序从运行时panic的状态中恢复并重新获得流程控制权。

  1: func recover() interface{}

PS:recover只有在defer调用的函数中有效。

果调用了内置函数recover,并且定义该defer语句的函数发生了panic异常,recover会使程序从panic中恢复,并返回panic value。导致panic异常的函数不会继续运行,但能正常返回。在未发生panic时调用recover,recover会返回nil。

  1: func TestA() {
  2: 	fmt.Println("func TestA{}")	
  3: }
  4: 
  5: func TestB() (err error) {
  6: 	defer func() {
  7: 		if x:= recover(); x!=nil{
  8: 			err = fmt.Errorf("internal error:%v", x)
  9: 		}
 10: 	}() // 调用匿名函数
 11: 	panic("func TestB():panic")
 12: }
 13: 
 14: func TestC() {
 15: 	fmt.Println("func TestC")
 16: }
 17: 
 18: func main() {
 19: 	TestA()
 20: 	err:=TestB()
 21: 	fmt.Println(err)
 22: 	TestC()
 23: }
 24: 
 25: >>> func TestA{}
 26: internal error:func TestB():panic
 27: func TestC
原文地址:https://www.cnblogs.com/haoqirui/p/10208467.html