The "Accept Interfaces, Return Structs" idiom means your function parameters should be interfaces to allow flexibility, while your return values should be concrete structs to maintain stability.
// Accept interface (flexible input)
func Process(r io.Reader) error {
// ... implementation
}
// Return struct (stable output)
func GetConfig() Config {
return Config{Timeout: 30}
}
This pattern prevents callers from needing to know implementation details when calling your function, while ensuring your function's output contract doesn't change unexpectedly.