userError 和 errors.New的实现与使用怎么理解?
来源:3-4 服务器统一出错处理2
qq_永远的稻米_0
2022-06-04 14:18:07
1. errors.New("xxx")的实现使用过程:
errors.New的时候,return了一个errorString的结构体,New的返回类型是error接口,接口也是个Error()为string类型的,希望老师用比较标准的方法解释一遍
2. userError接口的实现使用过程:类比error接口实现使用:
type userError string的内建类型,我对内建类型的理解其实就都是结构体,什么int,string我的理解都是struct的一种,这时候调用userError("xx")实际上就是对struct填充了数据,在调用userError.Error()或者user.Message()的时候实际上就是在实现接口中的方法,最后web.go中去user.Message()就是使用者,老师之前利用定义变量的接口类型,区分使用者和实现者是让我们更好的理解和解耦么?
userError("xxx")的时候自动调用了Error()方法,我就不太理解了,是塞入第一个参数对应接口的error接口,error接口第一个参数是Error(),那相当于直接调用了userError的Error()方法这个理解是对的?还是调用error接口的时候,类似于php魔术方法实现,底层的机制自动调用Error()?
1回答
ccmouse
2022-06-07
errors.New("xxx"):
使用者角度看:它返回了一个实现error接口的类型,具体什么类型使用者不关心。因为它的返回值实现error接口,所以可以调用Error()方法。
实现的角度:定义了一个结构体叫做errorString,它有一个Error()方法。所以它实现了error接口,所以可以当作error类型在errors.New函数中返回出去。而且这里用了小写errorString,就是不希望使用者知道我具体是什么类型,如何实现的。
userError的确思路一样,不过这里其实理解就是结构体,这样的说法不好,因为结构体特指struct。其实我理解你的意思,不过应当说,其实都是自定义类型。自定义类型可以定义方法。结构体也是自定义类型,可以定义方法。这里我用的是“别名”的方法来定义自定义类型,它也可以定义方法。而一旦实现了Error方法,不管是什么自定义类型,都认为实现了error接口。
最后同学说:userError("xxx")的时候自动调用了Error()方法。这个不对。userError("xxx")只是生成了一个userError实例,其实现其实是一个string类型,那这个string就被赋值为"xxx"。它有一个方法叫做Error()。只有当有人调用Error()方法的时候,才会把底层的"xxx"返回出去。
什么时候调用Error()方法,就是使用error接口的时候。比如fmt.Print的时候,就会调用Error()。
相似问题
回答 1
回答 1