Go

Explain method sets. Why does *T satisfy an interface when T does not?

Question 81MediumGo 1.22 to 1.25

The spec defines method sets as follows:

  • The method set of T contains methods declared with receiver T.
  • The method set of *T contains methods with receiver T and *T.
type Counter struct{ n int }

func (c *Counter) Inc()     { c.n++ }
func (c Counter) Get() int  { return c.n }

type Incrementer interface{ Inc() }

var _ Incrementer = &Counter{} // OK
// var _ Incrementer = Counter{} // compile error:
// Counter does not implement Incrementer (method Inc has pointer receiver)

Storing a value in an interface stores a copy, and that copy is not addressable. If the interface could call Inc on it, the method would change a hidden copy and the caller would never see the update. The language forbids that silent bug.

The rule is not the same as call syntax. c.Inc() compiles for an addressable variable c Counter because the compiler rewrites it to (&c).Inc(). That rewrite is available for direct calls but not for interface satisfaction.

More on Interfaces, Methods & Embedding

All 35 Interfaces, Methods & Embedding questions