Go Interfaces
An interface is a type that names a set of methods. A value of any type with those methods can be stored in the interface.
Satisfy an Interface
Shape names one method, Area. Square has that method, so a Square fits in a Shape value.
package main
import "fmt"
type Shape interface {
Area() int
}
type Square struct {
Side int
}
func (s Square) Area() int {
return s.Side * s.Side
}
func main() {
var shape Shape = Square{Side: 4}
fmt.Println(shape.Area())
}A Slice of an Interface
One slice holds a Square and a Rectangle. Each value answers Area in its own way.
package main
import "fmt"
type Shape interface {
Area() int
}
type Square struct {
Side int
}
func (s Square) Area() int {
return s.Side * s.Side
}
type Rectangle struct {
Width int
Height int
}
func (r Rectangle) Area() int {
return r.Width * r.Height
}
func main() {
shapes := []Shape{Square{Side: 3}, Rectangle{Width: 2, Height: 5}}
for _, shape := range shapes {
fmt.Println(shape.Area())
}
}Assert a Type
The assertion asks whether the Shape value holds a Square. The ok value reports the answer.
package main
import "fmt"
type Shape interface {
Area() int
}
type Square struct {
Side int
}
func (s Square) Area() int {
return s.Side * s.Side
}
func main() {
var shape Shape = Square{Side: 5}
square, ok := shape.(Square)
if ok {
fmt.Println(ok)
fmt.Println(square.Side)
}
}The Empty Interface
An empty interface value can hold any type. This slice holds an int and a string.
package main
import "fmt"
func main() {
values := []interface{}{42, "hello"}
for _, value := range values {
fmt.Println(value)
}
}Example
package main
import "fmt"
type Shape interface {
Area() int
}
type Square struct {
Side int
}
func (s Square) Area() int {
return s.Side * s.Side
}
type Rectangle struct {
Width int
Height int
}
func (r Rectangle) Area() int {
return r.Width * r.Height
}
func main() {
shapes := []Shape{Square{Side: 4}, Rectangle{Width: 3, Height: 5}, Square{Side: 2}}
total := 0
for _, shape := range shapes {
fmt.Println(shape.Area())
total += shape.Area()
}
fmt.Println("Total:", total)
}Key points
- Interface: a type that names a set of methods.
- A type satisfies an interface just by having its methods.
- An interface value can hold any type that satisfies it.
- Type assertion: an expression that gets the concrete value out of an interface.
- The ok form of an assertion reports whether the value has the named type.
- The empty interface is written interface{} and holds values of any type.
In this example, the slice holds two Squares and one Rectangle as Shape values. The loop prints the area of each shape in slice order. The same loop adds each area into total. The areas 16, 15, and 4 add up to the printed total of 35.
Note
The empty interface names no methods, so every type satisfies it.
Try it Yourself
Edit the code, then press Run.
Running is simulated ยท Go Playground
Exercise
What makes a type satisfy an interface in Go?