Embedded interface
You can embed interfaces in a struct.
package main import "fmt" type Mover interface { Move() } type Car struct { Mover }
But, what is embedded interface? Let's add some more fields to Car and print it with %v.
type Car struct { price int Mover speed int } func main() { var c Car fmt.Printf("%v\n", c) }
It prints,
$ go run main.go {0 <nil> 0}
As it printed out, Car has three fields. Embedded interface is just an anonymous interface fields.
Promoted methods
When interfaces are embedded, their methods are promoted automatically. That means methods of anonymous interface fields are seen as if they are methods of the embedding struct.
When you embed Mover interface in Car,
type Car struct { Mover }
it works as if Cars has Move() methods defined as following.
type Car struct { Mover } // promoted method func (c Car) Move() { c.Mover.Move() }
Note that calling Move() when the anonymous interface field is nil crashes the program.
func main() { var m Mover = Car{} // Field 'Mover' is nil. m.Move() // Crashes. nil dereference. }
Override promoted methods
You can override all or a part of promoted methods if you want.
type Car struct { Mover } type Wheel struct { } func (w Wheel) Move() { fmt.Println("wheel") } // Overrides promoted method func (c Car) Move() { fmt.Println("car") } func main() { var m Mover = Car{Wheel{}} m.Move() // Prints "car" }
Sort package has a good example of promoted method overriding.
Sort.Interface is as follows.
type Interface interface { Len() int Less(i, j int) bool Swap(i, j int) } func Sort(data Interface) { ... }
sort.Reverse returns the reverse ordered data. It uses a struct which embeds sort.Interface and overrides only Less() method.
func Reverse(data Interface) Interface { return &reverse{data} } type reverse struct { Interface // Interface embedding } // Overrides Less() only. No need to override promoted Len() and Swap(). func (r reverse) Less(i, j int) bool { return r.Interface.Less(j, i) }
Make use of interface embedding for test
By embedding interfaces, promoted methods of interfaces satisfies the interfaces even though the anonymous field is nil.
type Mover interface { Move() } type Car struct { Mover } func main() { // Car satisfies Mover interface because it has promoted Move() method. var m Mover = Car{} m.Move() // Crashes. nil dereference. }
If you need to test only a part of the methods, you only need to implement the method needed. In following code, Car implements only Move() method explicitly. Car satisfies MoveStopper interface because it has promoted Stop() method.
type MoveStopper interface { Move() Stop() } type Car struct { MoveStopper } func (c Car) Move() { fmt.Println("Move() tested") } func main() { var m MoveStopper = Car{} m.Move() }












