Interfaces are light-weight, and it's okay to define an interface that is just the subset of functionality your code needs.
This is exactly what the GP is saying.
I realize that this goes against the Go ethos of "don't think about the future; think about the now". Having said that, I don't understand why returning interfaces is seen as premature design while accepting interfaces is seen as reasonable and expected. Surely both can be examples of premature abstraction.
I'm certainly not saying that you should always return interfaces, or that returning interfaces will prevent all future refactoring pain. But working with interfaces instead of concrete types is more likely to allow your API to remain stable even as the implementation evolves.
Can you share why? Not trying to say you are wrong, but I am guessing that part of this stems from some limitations in the way interfaces work in Go, and this could make a good user experience report.
> “Accept interfaces, return structs”
Real example from personal (professional) life against that: Amazon AWS SDK defined S3 as a struct. That makes it bloody hard to mock during unit testing. I eventually ended up defining my own “s3iface” interface with corresponding mock to combat this, but now I have to repeat this for every program that uses it. Ok, I’ll separate it into its own package and include that everywhere. Wait, what was the point of the AWS SDK not doing this directly, again? Oh, look, they eventually ended up doing just that: providing an interface version of their S3 struct:
https://godoc.org/github.com/aws/aws-sdk-go/service/s3/s3ifa...
> Package s3iface provides an interface to enable mocking the Amazon Simple Storage Service service client for testing your code.
With the exact same name, to boot.
Please consider providing and returning interfaces. Even if your struct is the only type implementing it.