package main import "fmt" // Shape of thing (e.g. square) type Shape interface { // Signature of functions that implement this interface Area() float64 Perimeter() float64 } // Different types of shapes: type square struct { X float64 } // Area() implementation (see the name of the function) for the Shape interface of the square type (as a receiver) // receiver.field accesses the fields of the struct func (s square) Area() float64 { return s.X * s.X } // Perimeter() implementation (see the name) for the Shape interface of the square type (as a receiver) // receiver.field accesses the fields of the struct func (s square) Perimeter() float64 { return 4 * s.X } // Calculate the shape of a thing (area and perimeter) // Function using the interface Shape (see the input) -- has no output func Calculate(x Shape) { v, ok := x.(square) if ok { fmt.Println("Is a square:", v) } fmt.Println(x.Area()) fmt.Println(x.Perimeter()) } func main() { x := square{X: 10} fmt.Println("Perimeter:", x.Perimeter()) Calculate(x) }