每期一个小窍门: go处理异常的一些小窍门

go设计者更偏向于C的error处理方式, 快速失败是更简单高效的

我们可以利用error接口和多返回值来实现异常传递

error可以利用变量来复用 等价判断

var outOfRangeError = errors.New("number out of range")
var unknownError = errors.New("unknown type error")

func doSomeThing01(i interface{
    
    }) (string, error) {
    
    
	switch value := i.(type) {
    
    
	case int:
		if value > 10 {
    
    
			return "wrong", outOfRangeError
		}
		return " integer", nil
	case string:
		return " string", nil
	default:
		return " unknown", unknownError
	}

}

判断异常时, 异常逻辑在前, 即使有复杂业务逻辑判断, 也同样是扁平结构

func TestDoSomething(t *testing.T) {
    
    

	if msg01, err := doSomeThing01(1); err != nil {
    
    
		t.Log(err)
	} else {
    
    
		t.Log(msg01)
	}

	if msg01, err := doSomeThing01(200); err != nil {
    
    
		t.Log(err)
	} else {
    
    
		t.Log(msg01)
	}

	if msg01, err := doSomeThing01(false); err != nil {
    
    
		t.Log(err)
	} else {
    
    
		t.Log(msg01)
	}
}

但是也有类似java的异常捕获机制
通过panic抛出
通过defer来获取处理
通过recover使得程序继续运行
但是如果告警做的不好, 或者defer逻辑只是简单的记日志
Just let it crash!
那么更推荐让程序崩溃掉, 然后由运维层的恢复机制告警恢复, 健康检查这样也会检测到异常, 从而更好的解决本质问题

func doSomeThing02(i interface{
    
    }) string {
    
    
	defer func() {
    
    
		if err := recover(); err != nil {
    
    
			fmt.Println(err)
		}
	}()
	switch value := i.(type) {
    
    
	case int:
		if value > 10 {
    
    
			panic(outOfRangeError)
		}
		return " integer"
	case string:
		return " string"
	default:
		panic(unknownError)
	}

}
func TestDoSomething02(t *testing.T) {
    
    

	msg01 := doSomeThing02(1)
	t.Log(msg01)
	msg02 := doSomeThing02(200)
	t.Log(msg02)
	msg03 := doSomeThing02(false)
	t.Log(msg03)
}

猜你喜欢

转载自blog.csdn.net/qq_33709508/article/details/132258631
今日推荐