Ah the old nil values boxed into non-nil interfaces. Even after 8 years writing go code almost every day this still bites me occasionally. I've never seen code that actually uses this. I understand why it is the way it is but I hate it.
replies(4):
Loudest arguments against returning concrete types were on the terraform core team and the excuse was it makes testing easier. I disagree.
net.Dial (Conn, error)
image.Decode(r io.Reader) (Image, string, error)
sha256.NewXXX() hash.Hash
flate.NewReader(r io.Reader) io.ReadCloser
http.NewFileTransport(fs FileSystem) RoundTripper
Regarding `os.File`, the Go team even said: “If we were starting from scratch, we might do it differently.”That’s why Go added abstractions later like fs.FS and fs.File.
embed/fs.Open again deliberately breaks this.
Whereas consider its counterpart net.Conn. net.Conn is one of the most successful interfaces in the Go standard library. It’s the foundation of the net, net/http, tls, and net/rpc packages, and has been stable since Go 1.0. It didn't need a replacement fs.Fs.If you will always only ever have one implementation in absolute permanence and no mocking/fake/alternative implementation is ever required in eternity, return a concrete type. Otherwise, consider whether returning an interface makes more sense.
Go's standard library interfaces (like net.Conn) earned their place.
Premature interfaces calcify mistakes and that's what the guideline pushes back on.