不要 Panic
生产级的代码必须避免 panics 。panics 是级联故障的主要源头。如果错误发生,函数应该返回错误并且允许调用者决定如果处理它。
Bad | Good |
---|
func foo(bar string) { if len(bar) == 0 { panic("bar must not be empty") } // … }
func main() { if len(os.Args) != 2 { fmt.Println("USAGE: foo <bar>") os.Exit(1) } foo(os.Args[1]) }
|
func foo(bar string) error { if len(bar) == 0 return errors.New("bar must not be empty") } // … return nil }
func main() { if len(os.Args) != 2 { fmt.Println("USAGE: foo <bar>") os.Exit(1) } if err := foo(os.Args[1]); err != nil { panic(err) } }
|
Panic/recover 并不是错误处理策略。程序只有在遇到无法处理的情况下才可以 panic ,例如,nil 引用。程序初始化时是一个例外情况:程序启动时遇到需要终止执行的错误可能会 painc 。
var _statusTemplate = template.Must(template.New("name").Parse("_statusHTML"))
即使是在测试中,也应优先选择 t.Fatal
或 t.FailNow
而非 panic,以确保测试标记为失败。
Bad | Good |
---|
// func TestFoo(t testing.T)
f, err := ioutil.TempFile("", "test") if err != nil { panic("failed to set up test") }
|
// func TestFoo(t testing.T)
f, err := ioutil.TempFile("", "test") if err != nil { t.Fatal("failed to set up test") }
|