Golang 异常错误处理

2020-08-16 · xiejiahe

在Golang中与其他编程语言不太一样,没有 try catch 捕获行为。

Golang 处理异常错误,通过函数返回的 err 类型, 或 panic / recover

下面这段代码相当于 try/catch 捕获。

package main

import (
	"errors"
	"fmt"
)

// 只要执行此函数一定会抛出异常
func errFunc() error {
	return errors.New("type error")
}

func main() {
  err := errFunc()
  
  // 通过判断返回值,如果不是返回 nil 说明有异常
	if err != nil {
    fmt.Print(err)
	} else {
    // ...
  }
}

panic

panic内置函数停止当前goroutine的正常执行,当函数F调用panic时,函数F的正常执行被立即停止,然后运行所有在F函数中的defer函数,然后F返回到调用他的函数对于调用者G,F函数的行为就像panic一样,终止G的执行并运行G中所defer函数,此过程会一直继续执行到goroutine所有的函数。panic可以通过内置的recover来捕获。

将上面的代码进行稍微改造下:

package main

import (
	"errors"
	"fmt"
)

// 只要执行此函数一定会抛出异常
func errFunc() error {
	return errors.New("type error")
}

func main() {
  err := errFunc()
  
  // 通过判断返回值,如果不是返回 nil 说明有异常
	if err != nil {
      panic(err)
  }
  
  fmt.Print("一定不会执行到这里")
}

由于 err 发生了错误并执行 panic 使程序停止运行。

/private/var/folders/p_/np5btv6969b2nsyfp68q7_y00000gn/T/___go_build_app
panic: type error

goroutine 1 [running]:
main.main()
        /app/main.go:19 +0x5a

Process finished with exit code 2

recover

recover内置函数用来管理含有panic行为的goroutine,recover运行在defer函数中,获取panic抛出的错误值,并将程序恢复成正常执行的状态。如果在defer函数之外调用recover,那么recover不会停止并且捕获panic错误如果goroutine中没有panic或者捕获的panic的值为nil,recover的返回值也是nil。由此可见,recover的返回值表示当前goroutine是否有panic行为。

package main

import (
	"errors"
	"fmt"
)

func errFunc() error {
	return errors.New("type error")
}

func main() {
	err := errFunc()
	defer func() {
		if err := recover(); err != nil {
			fmt.Print("起死回生")
		}
	}()
	if err != nil {
		panic(err)
	}

}

recover 必须在 defer 语句,否则起不到作用。

总结

  • 通过判断函数返回的 err 如果不为 nil 说明有异常。
  • 调用 panic 会使整个程序终止运行。
  • recover 必须运行在defer函数内,可以让 panic 错误起死回生。
  • 考虑当前场景是否真正的需要使用 panic ,否则一般不要使用。
Golang
原创文章,转载请注明出处。