Idiomatic Go error-handling pattern: Must

地道 Go 错误处理模式:Must

UUID v7 Must

最近在使用 Go 官方 uuid 库生成 UUID v7 时注意到一种使用方式是:Must🔗,它的描述也很简单:

Must returns uuid if err is nil and panics otherwise.
func Must(uuid UUID, err error) UUID {
if err != nil {
panic(err)
}
return uuid
}

用途是「当错误不是一个可以恢复的选项时」,使用包装好的 Must 直接 panic 错误。

// 之前
id, err := uuid.NewV7()
if err != nil {
log.Fatalf("生成 UUID v7 失败: %v", err)
}
// 之后
mustId := uuid.Must(uuid.NewV7())

总结

Must 是 Go 生态的一种惯例用来操作当场 panic 也合理的数值
var (
validEmail = regexp.MustCompile(`^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$`)
validID = regexp.MustCompile(`^[a-z]+\[[0-9]+\]$`)
)
func init() {
templates = template.Must(template.ParseGlob("templates/*.html"))
}
  • 适合:初始化阶段(init()main() 开头、全局变量初始化),这时 panic 等同于启动失败,Fatal 终止整个程序是合理的。
  • 不适合:在 HTTP handler、goroutine 里或用户请求的处理路径中,panic 会导致整个服务崩溃或 recover 逻辑复杂化。

延伸阅读