可接受的 Golang 惯用嵌套错误处理?
Acceptable Golang idiomatic nested error handling?
我最近开始接触 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()
的错误 return 为零,我只想 运行 行 c.RegisterSomethingOnConnection
。
但是,由于早期 returns,我不喜欢上面的内容。早期的 return 使我感到不舒服,因为在长的 运行 中它会损害可读性并且模糊函数退出的确切时间。到目前为止,我的解决方案是执行以下操作:
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
我喜欢这样做有两个原因。首先,它防止 returning nil。其次,我发现它使代码更易于维护,因为您可以在 returning 之前轻松添加功能(即日志记录),并且某些路径不会因为早期的 return.[=15 而错过添加的功能=]
我所做的是可接受的惯用 Go 还是我只需要克服对早期 return 的厌恶并遵循该模式?
:
You should either handle an error, or not handle it but delegate it to
a higher level (to the caller). Handling the error and returning it is
bad practice as if the caller also does the same, the error might get
handled several times.
并查看:
Errors are Values 作者:罗布·派克。
Go Error Handling Techniques
你可以简化一下:
if err := datastore.Get(c, key, record); err != nil {
简化重复性错误处理:
In Go, error handling is important. The language's design and
conventions encourage you to explicitly check for errors where they
occur (as distinct from the convention in other languages of throwing
exceptions and sometimes catching them). In some cases this makes Go
code verbose, but fortunately there are some techniques you can use to
minimize repetitive error handling.
Consider an App Engine application with an HTTP handler that retrieves
a record from the datastore and formats it with a template.
func init() {
http.HandleFunc("/view", viewRecord)
}
func viewRecord(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
key := datastore.NewKey(c, "Record", r.FormValue("id"), 0, nil)
record := new(Record)
if err := datastore.Get(c, key, record); err != nil {
http.Error(w, err.Error(), 500)
return
}
if err := viewTemplate.Execute(w, record); err != nil {
http.Error(w, err.Error(), 500)
}
}
Go Prover之一是:
不要只检查错误,优雅地处理它们
我建议您阅读这篇 post 来自 Dave Cheney
我把亮点放在这里:
"There is no single way to handle errors. Instead, I believe Go’s error handling can be classified into the three core strategies"
- 哨兵错误:
if err == ErrSomething { … }
"Using sentinel values is the least flexible error handling strategy, as the caller must compare the result to predeclared value using the equality operator. This presents a problem when you want to provide more context, as returning a different error would will break the equality check."
- 错误类型
if err, ok := err.(SomeType); ok { … }
"An error type is a type that you create that implements the error interface. "
- 不透明错误
x, err := bar.Foo()
if err != nil {
return err
}
// use x
"I call this style opaque error handling, because while you know an error occurred, you don’t have the ability to see inside the error. As the caller, all you know about the result of the operation is that it worked, or it didn’t."
..阅读所有 post.
我认为错误处理的重要方面是不要只是检查错误,优雅地处理它们,希望这可以帮助到你。
我最近开始接触 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()
的错误 return 为零,我只想 运行 行 c.RegisterSomethingOnConnection
。
但是,由于早期 returns,我不喜欢上面的内容。早期的 return 使我感到不舒服,因为在长的 运行 中它会损害可读性并且模糊函数退出的确切时间。到目前为止,我的解决方案是执行以下操作:
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
我喜欢这样做有两个原因。首先,它防止 returning nil。其次,我发现它使代码更易于维护,因为您可以在 returning 之前轻松添加功能(即日志记录),并且某些路径不会因为早期的 return.[=15 而错过添加的功能=]
我所做的是可接受的惯用 Go 还是我只需要克服对早期 return 的厌恶并遵循该模式?
You should either handle an error, or not handle it but delegate it to a higher level (to the caller). Handling the error and returning it is bad practice as if the caller also does the same, the error might get handled several times.
并查看:
Errors are Values 作者:罗布·派克。
Go Error Handling Techniques
你可以简化一下:
if err := datastore.Get(c, key, record); err != nil {
简化重复性错误处理:
In Go, error handling is important. The language's design and conventions encourage you to explicitly check for errors where they occur (as distinct from the convention in other languages of throwing exceptions and sometimes catching them). In some cases this makes Go code verbose, but fortunately there are some techniques you can use to minimize repetitive error handling.
Consider an App Engine application with an HTTP handler that retrieves a record from the datastore and formats it with a template.
func init() { http.HandleFunc("/view", viewRecord) } func viewRecord(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) key := datastore.NewKey(c, "Record", r.FormValue("id"), 0, nil) record := new(Record) if err := datastore.Get(c, key, record); err != nil { http.Error(w, err.Error(), 500) return } if err := viewTemplate.Execute(w, record); err != nil { http.Error(w, err.Error(), 500) } }
Go Prover之一是:
不要只检查错误,优雅地处理它们
我建议您阅读这篇 post 来自 Dave Cheney
我把亮点放在这里:
"There is no single way to handle errors. Instead, I believe Go’s error handling can be classified into the three core strategies"
- 哨兵错误:
if err == ErrSomething { … }
"Using sentinel values is the least flexible error handling strategy, as the caller must compare the result to predeclared value using the equality operator. This presents a problem when you want to provide more context, as returning a different error would will break the equality check."
- 错误类型
if err, ok := err.(SomeType); ok { … }
"An error type is a type that you create that implements the error interface. "
- 不透明错误
x, err := bar.Foo()
if err != nil {
return err
}
// use x
"I call this style opaque error handling, because while you know an error occurred, you don’t have the ability to see inside the error. As the caller, all you know about the result of the operation is that it worked, or it didn’t."
..阅读所有 post.
我认为错误处理的重要方面是不要只是检查错误,优雅地处理它们,希望这可以帮助到你。