在Golang中处理nil和error的惯用方法是什么?
我有两个围棋功能:在Golang中处理nil和error的惯用方法是什么?,go,error-handling,Go,Error Handling,我有两个围棋功能: func sampleFunction () { u, err := findDog(1) if err != nil { // We couldn't find the dog, print a message. fmt.Println(err) // Custom error types. if _, ok := err.(*dneError); ok { fmt.Pr
func sampleFunction () {
u, err := findDog(1)
if err != nil {
// We couldn't find the dog, print a message.
fmt.Println(err)
// Custom error types.
if _, ok := err.(*dneError); ok {
fmt.Println("Custom dog dne error for the end-user here.")
}
} else {
// Do something with u.
u.doSomething() // Is this idiomatic in Go?
// Should we explicility check for u != nil?
// Or does the if check above need to return?
// (even if I would like the function to be longer)
}
}
// findDog returns a dog with a given ID. If not found, returns an error.
func findDog(id int) (*models.Dog, error) {
found, err := models.FindDog(id)
// Is this return scheme/flow too brittle?
if err != nil {
return nil, &dneError{fmt.Sprintf("Dog %d does not exist in the" +
"database: %s", id, err.Error())}
}
return found, nil
}
我只想确保我正确处理了错误和零,因此我的两个主要问题是:
我的目标是在程序员需要时正确地向他们显示错误/问题,并在用户需要时向他们显示错误/问题,同时遵守惯用标准。谢谢您的时间。我个人认为您处理得很好,只是一个建议,因为我不知道什么是
模型。FindDog(id)
我会再次检查找到的,如果这是nil
则返回错误,如果出错,则总结nil | | found==nil{
注意:这样做返回err.Error()
可能会失败是的,这是惯用的Go。因为错误是预先处理的,错误意味着失败,结果可能是nil
,或者可能是部分写入的缓冲区没有任何用处
另外,我还有一个建议,可以让事情变得更加习惯化。这个习惯用语类似于“缩进错误块,而不是代码”。您的示例函数中有一个if/else,但在大多数错误检查情况下(不是全部)你处理它并返回,然后跳过else,流程就继续了。为什么不必缩进呢?这会使很长的函数都易于阅读,因为函数的预期流程可以从上到下读取,而不必在if/else块之间来回跳转。至少在很多情况下是这样
我修改了一个拉入某人存储库的请求,因为我有一个if/else,其中if和return就足够了
编辑
所以我的回答让我有点困扰,现在我想起来了原因。非nil
error
返回通常表示其他返回值无效,但确实存在例外情况。请务必检查个别文档。
作为具体示例,请参见
如果ReadBytes在查找分隔符之前遇到错误,它将返回在错误之前读取的数据以及错误本身(通常是io.EOF)
是的,谢谢。“缩进错误块,而不是代码”的想法就是为什么我有这样的注释:“或者上面的if检查是否需要返回?(即使我希望函数更长一些)。我弄错了这个问题,但谢谢你-我会相应地修改我的代码。快速跟进:这是否意味着需要较短的函数?因为有一个长函数在顶部带有错误/返回似乎很危险。或者根本不危险?我想长函数本身被认为是不好的形式。@user2801352 Long函数不一定是糟糕的形式,但较小的函数更容易测试。我有一个生产函数,它一直遵循我提到的习惯用法。除了返回nil,err
块外,100多行都保持齐平状态。无可否认,它需要重构和收缩才能进行单元测试。但这也取决于代码。通常n对于错误,您只需将其传递回调用者。在您实际处理错误的情况下,您可能会有if/else块和任何必要的块。很多时候,这种处理是在最顶层的函数中完成的,因此通常错误只是通过返回alth来传递回堆栈,尽管如此,这会阻止错误的发生e类型的评论,我只想再次表示感谢。我将在我当前的项目中应用您的建议。谢谢,这是非常好的建议。如果err.Error()没有失败,也许我可以有两个单独的案例。或者如果err!=nil,就嵌套另一个。我会考虑一下,谢谢!等等,err.Error()怎么可能
失败?一个错误
是一个接口,它保证func error()字符串
存在。@RayfenWindspear在示例中是ifmodels.FindDog(id)return err=nil
由于错误为nilOh,代码将显示panic:runtime error:invalid memory address或nil pointer dereference
,因为您在该检查中使用了|
(or)。