Interfaces · 3 MIN READ

Pointer receiver, pointer method set

Predict whether a value or only a pointer satisfies an interface.

A method with a value receiver belongs to both T and *T. A method with a pointer receiver belongs only to *T.

So if any method that satisfies an interface has a pointer receiver, a plain value does not satisfy it — and the compiler says "does not implement", often pointing at a line that looks obviously correct. The fix is nearly always &value rather than changing the receiver.

SEE THE IDEA

Value and pointer types have different method sets

  1. 01

    Value receiver

    go
    func (t T) Read()

    Belongs to T and *T

  2. 02

    Pointer receiver

    go
    func (t *T) Write()

    Belongs to *T

  3. 03

    Interface check

    go
    var w Writer = &value

    The assigned type must supply Write

Convenient method-call syntax does not change interface satisfaction.

In practice

When an interface assignment fails, inspect the type of the assigned expression and the receiver of each required method. An addressable local value may call a pointer method through automatic addressing; that same value still lacks the pointer method in its own method set.

Watch out

Map elements are not addressable. Store pointers in the map or copy, modify and assign a value back.

Official reference ↗

Read and predict

go
package main

import "fmt"

type Counter struct{ n int }

func (c *Counter) Add()      { c.n++ }
func (c Counter) Total() int { return c.n }

type adder interface{ Add() }

func main() {
	var c Counter
	var a adder = &c
	a.Add()
	fmt.Println(c.Total())
}

Why must the assignment use &c, and what does this print?

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.