去error handling技术

我刚刚开始使用Go。 我的代码开始有很多这样的:

if err != nil { //handle err } 

或这个

  if err := rows.Scan(&some_column); err != nil { //handle err } 

在Go中有没有一些很好的成语/策略/最佳实践来检查和处理错误?

编辑澄清:我不是肚子疼或者build议Go团队想出更好的东西。 我问我是否做得对,还是错过了社区提出的一些技巧。 谢谢大家。

你的代码是惯用的,在我看来这是最好的做法。 有些人肯定会不同意,但我认为这是Golang标准库所见的风格。 换句话说,Go作者以这种方式编写error handling。

在这个问题六个月后,Rob Pike写了一篇名为“ 错误就是价值 ”的博客文章。

在那里他认为,你不需要按照OP提出的方式进行编程,而是在标准库中的几个地方使用不同的模式。

当然,涉及错误值的常见语句是testing它是否为零,但是可以用错误值做无数其他事情,并且应用其他一些东西可以使程序更好,从而消除了大量的样板如果每个错误都与死记硬背检查相关,那么就会出现这种情况。

使用该语言来简化error handling。

但要记住:无论你做什么,总是检查你的错误!

这是一个很好的阅读。

我同意jnml的答案,他们都是惯用的代码,并添加以下内容:

你的第一个例子:

 if err != nil { //handle err } 

在处理多个返回值时更为习惯。 例如:

 val, err := someFunc() if err != nil { //handle err } //do stuff with val 

你的第二个例子是很好的速记,只处理err值。 如果函数只返回一个error ,或者如果故意忽略error以外的返回值,这将适用。 作为一个例子,这有时与ReaderWriter函数一起使用,它返回一个写入字节数的int (有时是不必要的信息)和一个error

 if _, err := f.Read(file); err != nil { //handle err } //do stuff with f 

第二种forms被称为使用if初始化语句 。

所以就最佳实践而言,就我所知(除了使用“错误”包在需要时使用“错误”包创build新错误),您几乎涵盖了所有需要了解Go的错误!

编辑:如果你发现你真的不能没有例外生活,你可以模仿他们deferpanicrecover

我制作了一个精简的error handling库,并通过Go函数队列pipe道。

你可以在这里find它: https : //github.com/go-on/queue

它有一个紧凑和冗长的句法变体。 下面是一个短语法的例子:

 import "github.com/go-on/queue/q" func SaveUser(w http.ResponseWriter, rq *http.Request) { u := &User{} err := qQ( ioutil.ReadAll, rq.Body, // read json (returns json and error) )( // qV pipes the json from the previous function call json.Unmarshal, qV, u, // unmarshal json from above (returns error) )( u.Validate, // validate the user (returns error) )( u.Save, // save the user (returns error) )( ok, w, // send the "ok" message (returns no error) ).Run() if err != nil { switch err { case *json.SyntaxError: ... } } } 

请注意,由于它使用了reflection,因此性能开销很小。

此外,这不是惯用的代码,所以你会想在你自己的项目中使用它,或者如果你的团队同意使用它。

处理golang和其他语言中的错误的“策略”是不断地在调用堆栈中传播错误,直到在调用堆栈中足够高以处理该错误为止。 如果您尝试过早地处理该错误,那么您可能最终会重复代码。 如果你处理得太晚,那么你会在代码中破坏一些东西。 Golang使这个过程变得非常简单,因为它能够非常清楚地处理给定位置的错误还是传播错误。

如果你会忽略这个错误,一个简单的_将会很清楚地揭示这个事实。 如果您正在处理它,那么您正在处理的错误的确切情况是清楚的,因为您将在if语句中检查它。

就像上面说的人一样,一个错误实际上只是一个正常值。 这样对待它。

可以清理你的error handling代码,类似的错误(因为错误是你必须小心的值),并写入一个函数,你传入的错误来处理错误。 那么每次都不用写“if err = nil {}”。 再次,这只会导致清理代码,但我不认为这是做事的惯用方式。

再次,只因为你可以不意味着你应该

大多数在行业中,遵循golang文档中提到的标准规则error handling和Go 。 它也有助于项目的文档生成。

goerr允许用function来处理错误

 package main import "github.com/goerr/goerr" import "fmt" func ok(err error) { if err != nil { goerr.Return(err) // returns the error from do_somethingN() to main() // sequence() is terminated } } func sequence() error { ok(do_something1()) ok(do_something2()) ok(do_something3()) return nil /// 1,2,3 succeeded } func do_something1() error { return nil } func do_something2() error { return fmt.Errorf("2") } func do_something3() error { fmt.Println("DOING 3") return nil } func main() { err_do_something := goerr.OR1(sequence) // handle errors fmt.Println(err_do_something) } 

如果你想精确地控制错误,这可能不是解决scheme,但是对于我来说,大多数时候,任何错误都是阻碍。

所以,我用function来代替。

 func Err(err error) { if err!=nil { fmt.Println("Oops", err) os.Exit(1) } } fi, err := os.Open("mmm.txt") Err(err)