零并不总是零
“什么?在这里写什么?” 你问。 现在,我将其全部放下。
当我开始学习语言时,我认为我不会遇到这种狭case的情况。 修改可迭代的集合也是不合理的。
例如:
func Foo() error { var err *os.PathError = nil return err } func main() { err := Foo() fmt.Println(err) // <nil> fmt.Println(err == nil) // false }
哇!
什么是接口?
转到go runtime / runtime2.go软件包文件,请参阅:
type itab struct { // 40 bytes on a 64bit arch inter *interfacetype _type *_type ... }
接口存储接口的类型和值本身的类型。
在AND值和类型为nil的情况下,任何接口的值(不仅是错误)都是nil。
Foo函数返回类型为* os.PathError的nil,我们将结果与类型为nil的nil进行比较,由此得出它们的不等式。
也许很多人都知道这一点,但是很少有人思考如何在实践中融入它。
我的例子
type Response struct { Result ResponseResult `json:"result,omitempty"` Error *ResponseError `json:"error,omitempty"` } type ResponseError struct { Message string `json:"message"` } func (e *ResponseError) Error() string { return e.Message } ... func (s *NotificationService) NotifyIfError(w *ResponseWriter) error { ... var res handlers.Response _ = json.Unmarshal(body, &res) if res.Error == nil { return } return s.NotifyError(err) }
响应总是有结果或错误。
如果有错误,我们会在必要时通过通知服务将其发送。
在服务内部,将调用Error方法,并且由于我们的值为nil,我们会感到恐慌。
怎么办
严格返回接口类型的接口。
如果发生错误-错误类型。
func (s *NotificationService) NotifyIfError(w *ResponseWriter) error { ... var res Response _ = json.Unmarshal(body, &res) var err error = res.Error return s.NotifyError(err) }
令我惊讶的是,该技术也不起作用。
事实证明,当为err变量赋值时,我们还将有关类型的初始信息传递给它,该信息不是nil。
func (s *NotificationService) NotifyIfError(w *ResponseWriter) error { ... if e, ok := err.(*ResponseError); ok && e == nil { return s.NotifyError(err) } return nil }
是的,这项技术有效。
但是,老实说,我们负担不起检查将要传输的所有错误类型。
可能是数据库驱动程序中的所有错误,我们所有的内部错误以及其他垃圾。
我看到的最合理的选择是:
func (s *NotificationService) NotifyIfError(w *ResponseWriter) error { var err error ... var res Response _ = json.Unmarshal(body, &res) if res.Error != nil { return s.NotifyError(err) } return nil }
首先,我们声明了一个类型为error的变量,因为它的值和类型均为nil。
在将类型和值传递给此变量之前,让我们检查类型及其在nil上的值。
这将使我们不要惊慌失措。
最后
您可以更进一步,使用Response,OptionalError或ErrorOrNil类型实现“可选”错误,如下所示:
func (r *Response) ErrorOrNil() error { if r.Error == nil { return nil } return r.Error }
注意事项
在Go Wiki注释中,代码回顾是该主题中有关接口的注释:而是返回一个具体的类型,并让使用者模拟生产者实现。
我注意到上面的舞蹈与这无关。
当您知道要返还利息时,我的便笺使您不必惊慌,并且在出现错误的情况下,您始终希望返回界面。
但是,如果您有能力返回某个类型,则将其返回。
参考文献
内部人
我是
领英
电报
推特
Github