Types you define · 3 MIN READ

A method is a function with a receiver

Put a method on your own type and choose the receiver deliberately.

A method is declared outside the type, with the receiver in parentheses before the name: func (r Rect) Area() int. There is no class body, and methods can be attached to any type you declared in this package — including type Celsius float64, not only structs.

The receiver is a copy unless it is a pointer. func (r Rect) Grow() mutates a copy and the caller sees nothing; func (r *Rect) Grow() mutates the original. Go calls either form for you — r.Grow() works on an addressable value whichever receiver you chose — so the compiler will not warn you that the mutation went nowhere.

The convention is to pick one kind of receiver for the whole type. A type with some value methods and some pointer methods has a method set that changes depending on whether you hold a value or a pointer, and that is where "it does not satisfy the interface" comes from.

SEE THE IDEA

A receiver gives a function a home

  1. 01

    Value

    go
    type Counter struct { N int }

    The receiver type owns the method

  2. 02

    Method

    go
    func (c *Counter) Add()

    A pointer receiver can mutate c

  3. 03

    Call

    go
    counter.Add()

    The receiver supplies the first operand

The receiver is an explicit part of the method declaration.

In practice

Choose pointer receivers when a method needs to change the receiver or when copying the value would be inappropriate. Keep receiver naming short and consistent across methods. Whether a value satisfies an interface is decided by its method set, which is a separate rule from convenient call syntax.

Watch out

Go may take the address of an addressable value for a method call. That convenience does not add pointer methods to its value method set.

Official reference ↗

Work through the exercise

go
package main

type Counter struct {
	Total int
}

// Add should increase the counter by n, and the change must be
// visible to the caller. Total should report the current value.

func main() {
	c := Counter{}
	c.Add(3)
	println(c.Value())
}
Try it yourself

Trace each value and write down your reasoning. Copy the source into GopherForge or your local Go environment to compile and check it. This web page does not execute your code or send it to a compiler service.

Progress stays in this browser. No account needed.