Go error深入

1、Go error本质上是什么?

type error interface {
	Error() string
}

说白了,error实际上是一个接口,接口里面就一个方法:Error() string

2、如何自定义错误类型

2.1 既然是接口,那就定义一个实现类

package main

import (
	"fmt"
	"reflect"
)

type MyErr1 struct {
}

func (this *MyErr1) Error() string {
	return "this is MyErr1"
}

func main() {
	var err error = nil
	err = &MyErr1{}
	fmt.Println(reflect.TypeOf(err))
	fmt.Println("type err1-->", err)
}

*main.MyErr1
type err1--> this is MyErr1

2.2 也可以借助fmt,快速创建一个错误值

package main

import (
	"fmt"
	"reflect"
)

func main() {
	err := fmt.Errorf("this is MyErr2")
	fmt.Println(reflect.TypeOf(err))
	fmt.Println("type err2-->", err)
}

*errors.errorString
type err2--> this is MyErr2

2.3 还可以借助errors包

package main

import (
	"errors"
	"fmt"
	"reflect"
)

func main() {
	err := errors.New("this is MyErr3")
	fmt.Println(reflect.TypeOf(err))
	fmt.Println("type err3-->", err)
}

*errors.errorString
type err3--> this is MyErr3

可以看到系统快速创建的error都是*errors.errorString类型的

3、如何判断错误类型

一个方法可能返回多种错误类型,调用方常常需要根据不同类型的错误做出不同的处理。区分错误类型是非常常见和重要的。

我们以*errors.errorString来看看如何区分错误类型,常见的做法是这样子的

package main

import (
	"errors"
	"fmt"
)

var err_1 = errors.New("this is err type 1")
var err_2 = errors.New("this is err type 2")

func main() {
	j, err := tryErr(-10)
	if err == err_1 {
		fmt.Println(err)
		return
	}
	if err == err_2 {
		fmt.Println(err)
		return
	}
	fmt.Println("success", j)
}

func tryErr(i int) (int, error) {
	if i < 0 {
		return -1, err_1
	} else if i == 0 {
		return -1, err_2
	} else {
		return i, nil
	}
}

可以看到这种“常见做法”里面,错误是作为一个值来判断的。这种方式与Java里面的异常机制又很大区别

try{
...
}
catch(Exception1 e1){
...
}
catch(Exception2 e2){
...
}

这个是java里面的异常机制,可以看到catch是按照类型来匹配的。

这两种机制孰优孰劣呢?很明显,以值来判断错误类型只能携带错误类型本身的类型信息。不能反映出错误的更多细节。

4、Go里面以错误值的类型判断错误类型——使用类型断言

package main

import (
	"fmt"
	"strconv"
)

type MyErr1 struct {
	err_mag string //错误消息信息
}

func (this *MyErr1) Error() string {
	return this.err_mag
}

type MyErr2 struct {
	err_mag string //错误消息信息
}

func (this *MyErr2) Error() string {
	return this.err_mag
}

func main() {
	j, err := tryErr(-10)
	switch err.(type) {
	case *MyErr1:
		fmt.Println(err)
		return
	case *MyErr2:
		fmt.Println(err)
		return
	default:
		fmt.Println("success", j)
	}
}

func tryErr(i int) (int, error) {
	if i < 0 {
		return -1, &MyErr1{"error message 1-->" + strconv.Itoa(i)}
	} else if i == 0 {
		return -1, &MyErr2{"error message 2-->" + strconv.Itoa(i)}
	} else {
		return i, nil
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值