Structs, methods and interfaces

Group fields in a struct, attach methods, and accept any type that has the right methods with an interface.

Runs in Zerethon IDE · Go 1.27 Official Go documentation ↗
main.go
package main

import (
	"fmt"
	"math"
)

type Shape interface {
	Area() float64
}

type Rect struct {
	Width, Height float64
}

type Circle struct {
	Radius float64
}

func (r Rect) Area() float64 {
	return r.Width * r.Height
}

func (r Rect) String() string {
	return fmt.Sprintf("Rect(%gx%g)", r.Width, r.Height)
}

func (r *Rect) Scale(factor float64) {
	r.Width *= factor
	r.Height *= factor
}

func (c Circle) Area() float64 {
	return math.Pi * c.Radius * c.Radius
}

func main() {
	r := Rect{Width: 3, Height: 4}
	r.Scale(2)
	fmt.Println(r, r.Area())

	shapes := []Shape{r, Circle{Radius: 1}}
	for _, s := range shapes {
		fmt.Printf("%.2f\n", s.Area())
	}
}

Output

Rect(6x8) 48
48.00
3.14
  • Go has no classes. A type gets methods by declaring them with a receiver: func (r Rect) Area().
  • A pointer receiver (*Rect) can change the value; a value receiver works on a copy.
  • A type implements an interface just by having its methods — there is no implements keyword.
  • A String() string method controls how fmt prints the value.
  • Names starting with a capital letter are exported (visible to other packages); lower-case names are private to the package.