go - 可接受的 Golang 惯用嵌套错误处理?

标签 go idioms

我最近开始接触 Go 并且看到了很多关于如何进行错误处理的讨论。

我看到的布局如下:

err := DoSomething()
if err != nil {
   //handle
}
// continue

通常在管理 amqp 连接时,我的条件是只有在错误为零时我才想继续,因为那时我需要对连接做一些事情:

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

如您所见,如果 Connect() 返回的错误为 nil,我只想运行 c.RegisterSomethingOnConnection 行。

但是,由于提前返回,我不喜欢上面的内容。提前返回让我感到不舒服,因为从长远来看,它会损害可读性并模糊函数退出的确切时间。到目前为止,我的解决方案是执行以下操作:

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

我喜欢这样做有两个原因。首先,它防止返回 nil。其次,我发现它使代码更易于维护,因为您可以在返回之前轻松添加功能(即日志记录),并且不会有某些路径由于提前返回而错过添加的功能。

我所做的是可接受的惯用 Go 还是我只需要克服对提前返回的厌恶并遵循该模式?

最佳答案

其中一个 Go Prover 是:

不要只是检查错误,要优雅地处理它们

我推荐你阅读这篇 post来自戴夫切尼

我把亮点放在这里:

“没有单一的方法来处理错误。相反,我认为 Go 的错误处理可以分为三个核心策略”

  • 哨兵错误:

if err == ErrSomething { … }

“使用标记值是最不灵活的错误处理策略,因为调用者必须使用相等运算符将结果与预先声明的值进行比较。当您想要提供更多上下文时,这会出现问题,因为会返回不同的错误会破坏相等性检查。”

  • 错误类型

如果出错,ok := err.(SomeType);好的{…}

“错误类型是您创建的实现错误接口(interface)的类型。”

  • 不透明的错误

x, 错误 := bar.Foo() 如果错误!=无{ 返回错误 } //使用 x

“我将这种风格称为不透明的错误处理,因为虽然您知道发生了错误,但您无法看到错误的内部。作为调用者,您所知道的操作结果是它起作用了,或者没有起作用。”

....阅读所有帖子。

我认为错误处理的重要方面是不要只是检查错误,优雅地处理它们,我希望这可以帮助到你。

关于go - 可接受的 Golang 惯用嵌套错误处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39639853/

相关文章:

reflection - 将 reflect.value 转换为 reflect.method

go-routines 和 channels in go

go - 模板.执行(): invalid memory address or nil pointer dereference

c++ - 即时推导

c++ - 如何减少内核中分支/if 语句的数量?

go - 等待所有 goroutine 完成并合并结果

docker - skaffold 不会在 minikube 中重新加载 golang 代码

python - 惯用的 Python : `in` keyword on literal

python - 使用 Counter 对象从两个列表创建字典

c - 重新学习 C : New idioms?