Go error handling can be a bit verbose. There are a lot of places where errors
are unlikely or where they are so critical that a panic is preferred. Because of
this there are lots of Must* -helpers in various packages. E.g.
regexp.MustCompile.
Let’s take a closer look at regexp.MustCompile:
// MustCompile is like Compile but panics if the expression cannot be parsed.
// It simplifies safe initialization of global variables holding compiled regular
// expressions.
func MustCompile(str string) *Regexp {
regexp, err := Compile(str)
if err != nil {
panic(`regexp: Compile(` + quote(str) + `): ` + err.Error())
}
return regexp
}
These helpers have naturally been written before generics were introduced. They typically couldn’t be reused, because different functions have different return types. But Go has had generics for a while now, so we can use them to implement a … generic Must-function:
func Must[T any](v T, err error) T {
if err != nil {
panic(err)
}
return v
}
Usage is quite simple:
re := regexp.MustCompile(`\d+`)
re2 := Must(regexp.Compile(`\d+`))
We could also define a currying version:
func CurryMust[T any, U any](f func(T) (U, error)) func(T) U {
return func(v T) U {
w, err := f(v)
if err != nil {
panic(err)
}
return w
}
}
But using it isn’t necessarily any nicer:
re := CurryMust(regexp.Compile)(`\d+`)
compile := CurryMust(regexp.Compile)
re2 := compile(`\d+`)