Golang 1.20 is out and one the most interesting features for me has been multiple errors. I wrote about them in Golang 1.20 multiple errors.
I was recently researching some Go idioms and patterns for a lightning talk and stumbled upon what I would defined as “anonymous interface” (the correct term would be “anonymous type assertion” probably).
I would defined it as a one-off interface declaration used to answer the question: “does this struct implement this method?”
This helps solving one of the open questions of my previous blog post on errors: how to assess if an error is a “joined error”? We know that for an error to wrap multiple errors it has to implement the Unwrap
method with this signature:
Unwrap() []error
Go does not provide an out of the box interface for this case, but using an anonymous interface allow us to overcome this limitation easily:
err := errors.Join(err1, err2, err3)
if e, ok := err.(interface{ Unwrap() []error }), ok {
for _, ue := range e.Unwrap() {
fmt.Println("Unwrapped: ", ue)
}
}
This is not as neat as a i.e. errors.Multiple
interface out of the box (but implementing it is straightforward and also helps with inversion of dependency principle) but I still find it pretty readable.
It also allowed me to discover a powerful Golang pattern, as the same pattern can be used to asses behaviour of a struct without knowing anything of the interfaces the same struct implements.
I also found a thread on in on Reddit, with this and other use cases! Common complain, to which I agree is: why don’t make it an exported interface? (The answer is probably to keep the public API small and help with forward compatibility)