Info

When working with struct definitions, functions, interfaces and such, always try to work with interfaces, rather than concrete types. Accept Interfaces, return concrete structs.

Example

package main
 
import "fmt"
 
// Define an interface
type Reader interface {
	Read() string
}
 
// Concrete type that implements Reader
type FileReader struct{}
 
func (f FileReader) Read() string {
	return "data from file"
}
 
// A function that ACCEPTS an interface but RETURNS a concrete type
func Process(r Reader) Result {
	data := r.Read()
	return Result{Content: data}
}
 
// A concrete return type
type Result struct {
	Content string
}
 
func main() {
	var r Reader = FileReader{}     // assign concrete to interface
	result := Process(r)            // function accepts interface, returns concrete
	fmt.Println(result.Content)     // prints: data from file
}