Fuz*_*ker 6 idioms idiomatic go
我最近进入Go并看到了很多关于如何进行错误处理的讨论.
我看到的模式如下:
err := DoSomething()
if err != nil {
//handle
}
// continue
Run Code Online (Sandbox Code Playgroud)
经常在管理amqp连接时,我的条件是我只想在错误为nil时继续,因为那时我需要在连接上做一些事情:
c, err := Connect()
if err != nil {
return nil, err
}
s,err := c.RegisterSomethingOnConnection()
if err != nil {
return nil, err
}
val, err := s.DoSomething()
return val, err
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,c.RegisterSomethingOnConnection如果返回的错误Connect()是nil,我只想运行该行.
但是,由于提前退货,我不喜欢上述情况.早期的回报让我感到不舒服,因为从长远来看,它会损害可读性,并且在功能退出时会完全模糊.到目前为止,我的解决方案是执行以下操作:
var err error
var val ReturnType
c,err := Connect()
if err == nil {
s,err := c.RegisterSomethingOnConnection()
if err == nil {
val,err = s.DoSomething()
}
}
return val,err
Run Code Online (Sandbox Code Playgroud)
我喜欢这样做有两个原因.首先,它可以防止返回零.其次,我发现它使代码更易于维护,因为您可以在返回(即日志记录)之前轻松添加功能,并且由于提前返回而没有某些路径错过添加的功能.
是我做了什么可以接受惯用Go或者我只是需要克服我对早期回报的厌恶并遵循那种模式?
Go Prover 之一是:
\n\nDon\xe2\x80\x99t 只是检查错误,优雅地处理它们
\n\n我建议您阅读戴夫·切尼的这篇文章
\n\n我把重点放在这里:
\n\n“错误处理没有单一的方法。相反,我认为 Go\xe2\x80\x99s 错误处理可以分为三个核心策略”
\n\nif err == ErrSomething { \xe2\x80\xa6 }
“使用哨兵值是最不灵活的错误处理策略,因为调用者必须使用相等运算符将结果与预先声明的值进行比较。当您想要提供更多上下文时,这会出现问题,因为返回不同的错误将破坏相等检查”。
\n\nif err, ok := err.(SomeType); ok { \xe2\x80\xa6 }
“错误类型是您创建的实现错误接口的类型。”
\n\n\nx, err := bar.Foo()\n if err != nil {\n return err\n }\n// use x\n
“我将这种风格称为不透明错误处理,因为虽然您知道发生了错误,但您没有能力看到错误的内部。作为调用者,您所知道的操作结果是有效,或者没有\xe2\x80\x99t。”
\n\n....阅读所有帖子。
\n\n我认为错误处理的重要方面是Don\xe2\x80\x99t 只是检查错误,优雅地处理它们,我希望这可以帮助你。
\n