Methods

A method is a function that you can attach to a type

type Loc struct {
	X int
	Y int
}

func (l *Loc) Add(dx, dy int) {
	l.X += dx
	l.Y += dy
}

func (l *Loc) ToString() string {
	return fmt.Sprintf("X: %v, Y: %v", l.X, l.Y)
}

func main() {
	l := Loc{X: 2, Y: 3}

	l.Add(4, 5)

	fmt.Println(l.ToString())
}

Methods on non-struct

You can only define methods for types defined in the package, thus you must create a work around for types like int or float

You can do this by creating a type alias

type Int int

func (i Int) Square() Int {
	return i * i
}

func main() {
	sqr := Int(10).Square()

	fmt.Println(sqr)
}

Value vs Pointer Receivers

Value receiver:

Pointer receiver:

Note: considered very bad practice to mix an interface with value and pointer receivers

type Int int

func (i Int) SquareValueReceiver() Int {
	return i * i
}

func (i *Int) SquarePointerReceiver() {
	if i != nil {
		*i = *i * *i
	}
}

func main() {
	val := Int(10)

	val.SquareValueReceiver()
	fmt.Printf("Value Receiver: %v\n", val)

	val.SquarePointerReceiver()
	fmt.Printf("Pointer Receiver: %v", val)
}

/*
Output:
	Value Receiver: 10
	Pointer Receiver: 100
*/