_Interfaces_ are named collections of method signatures. | ||
package main |
||
import ( |
||
"fmt" |
||
"math" |
||
) |
||
Here's a basic interface for geometric shapes. | type geometry interface { |
|
area() float64 |
||
perim() float64 |
||
} |
||
For our example we'll implement this interface on `rect` and `circle` types. | type rect struct { |
|
width, height float64 |
||
} |
||
type circle struct { |
||
radius float64 |
||
} |
||
To implement an interface in Go, we just need to implement all the methods in the interface. Here we implement `geometry` on `rect`s. | func (r rect) area() float64 { |
|
return r.width * r.height |
||
} |
||
func (r rect) perim() float64 { |
||
return 2*r.width + 2*r.height |
||
} |
||
The implementation for `circle`s. | func (c circle) area() float64 { |
|
return math.Pi * c.radius * c.radius |
||
} |
||
func (c circle) perim() float64 { |
||
return 2 * math.Pi * c.radius |
||
} |
||
If a variable has an interface type, then we can call methods that are in the named interface. Here's a generic `measure` function taking advantage of this to work on any `geometry`. | func measure(g geometry) { |
|
fmt.Println(g) |
||
fmt.Println(g.area()) |
||
fmt.Println(g.perim()) |
||
} |
||
func main() { |
||
r := rect{width: 3, height: 4} |
||
c := circle{radius: 5} |
||
The `circle` and `rect` struct types both implement the `geometry` interface so we can use instances of these structs as arguments to `measure`. | measure(r) |
|
measure(c) |
{3 4} 12 14 {5} 78.53981633974483 31.41592653589793 |
|
} |