【Go基础】错误处理

两种类型

error:可以被处理的错误,只是一个内置的接口(意味着可以自定义error类型并使用,开发中间件时可能会用)
panic:非常严重不可恢复的错误

errors包

常用方法有4个:

  1. New:创建一个新的 error
  2. Is:判断是不是特定的某个error
  3. As:类型转换为特定的error(用得不多)
  4. Unwrap:解除包装,返回被包装的 error

示例:

package main

import (
	"errors"
	"fmt"
)

func main() {
	var err error = &MyError{}
	println(err.Error())

	ErrorsPkg()
}

type MyError struct {
}

func (m *MyError) Error() string {
	return "Hello, it's my error"
}

func ErrorsPkg()  {
	err := &MyError{}
	// 使用 %w 占位符,返回的是一个新错误
	// wrappedErr 是一个新类型,fmt.wrapError
	wrappedErr := fmt.Errorf("this is an wrapped error %w", err)

	// 再解出来
	if err == errors.Unwrap(wrappedErr) {
		fmt.Println("unwrapped")
	}
	
	if errors.Is(wrappedErr, err) {
		// 虽然被包了一下,但是 Is 会逐层解除包装,判断是不是该错误
		fmt.Println("wrapped is err")
	}

	copyErr := &MyError{}
	// 这里尝试将 wrappedErr转换为 MyError
	// 注意我们使用了两次的取地址符号
	if errors.As(wrappedErr, &copyErr) {
		fmt.Println("convert error")
	}
}

panic

从panic中恢复:recover(场景:用了别人的代码,别人没有合理使用panic,自己的话还是用error)

示例:

package main

import "fmt"

func main() {
	defer func() {
		if data := recover(); data != nil {
			fmt.Printf("hello, panic: %v\n", data)
		}
		fmt.Println("恢复之后从这里继续执行")
	}()

	panic("Boom")
	fmt.Println("这里将不会执行下来")
}

使用原则

  1. 遇事不决选 error
  2. 当怀疑可以用 error 的时候,就说明不需要 panic
  3. 一般情况下,只有快速失败的过程,才会考虑panic

defer

用于在方法返回之前执行某些动作(类似于Java中的finally),一般用来释放资源(如锁等)。
执行顺序:像栈一样,先进后出。

你可能感兴趣的:(golang,开发语言,后端)