20210217从golang的error这一内置接口和结构类net.OpError{}了解接口作为返回值的正确使用方式 - ziyouzy/2021blog GitHub Wiki
首先要明确的是error这个golang语言自身的内置数据类型是一个接口,而net.OpError{}是个结构类对象
使用前者不需要预先import "errors",使用后者需要预先import "net"
先看看error的本体(具体是在哪个.go文件实现的并不重要):
type error interface{
Error() string //Error()是每一个订制的error对象需要填充的错误消息,可以理解成是一个字段Error
}
也就是说任何实现了Error() string方法的结构类都可以成为一个error实现返回值
接下来我们再看net.OpError{}以及他的方法:
type OpError struct {
Op string
Net string
Addr Addr
Err error
}
func (e *OpError) Unwrap() error {}
func (e *OpError) Error() string {}
func (e *OpError) Timeout() bool {}
func (e *OpError) Temporary() bool {}
于是可以看到4个中包含了一个实现了error接口的方法,从而他就可以直接作为error类型的返回值了
有些神似net.Conn这个接口,以后设计的时候,自己设计的连接对象类肯定会包含net.Conn所需要实现的方法,之后去写额外的方法也是很顺其自然的事,golang的设计者就是希望大家用这种设计模式的。
接下来再看看errors.New(string)函数,注意他是一个类似工厂函数的函数,而不是某个结构类的方法
更重要的是,他才是程序员日常编程时定义一个错误最主流的使用方式,存在于package errors的errors.go文件中
func New(text string) error {
return &errorString{text}
}
type errorString struct {
s string
}
func (e *errorString) Error() string {
return e.s
}
他并不是很难理解,传入一个string,返回一个结构类
errors.errorString{}在逻辑地位上等同于net.OpError{}的存在
思路变得超级的清晰了