Method values, part 2

November 8, 2023

Today we finish up the spec’s section on method values, with some very non-surprising bits:

Method values

As with selectors, a reference to a non-interface method with a value receiver using a pointer will automatically dereference that pointer: pt.Mv is equivalent to (*pt).Mv.

As with method calls, a reference to a non-interface method with a pointer receiver using an addressable value will automatically take the address of that value: t.Mp is equivalent to (&t).Mp.

f := t.Mv; f(7)   // like t.Mv(7)
f := pt.Mp; f(7)  // like pt.Mp(7)
f := pt.Mv; f(7)  // like (*pt).Mv(7)
f := t.Mp; f(7)   // like (&t).Mp(7)
f := makeT().Mp   // invalid: result of makeT() is not addressable

Although the examples above use non-interface types, it is also legal to create a method value from a value of interface type.

var i interface { M(int) } = myVal
f := i.M; f(7)  // like i.M(7)

So let’s just explicitly review a complete example:

type Person struct {
	Name string
}

func (p Person) Hi() { // Value receiver
	fmt.Printf("Hi, %s", p.Name)
}

func (p *Person) Hello() { // Pointer receiver
	fmt.Printf("Hello, %s", p.Name)
}

var b = &Person{Name: "Bob"} // b is of type *Person

b.Hi() // equivalent to (*b).Hi

var a = Person{Name: "Alice"} // a is of type Person

a.Hello() // equivalent to (&a).Hello

Quotes from The Go Programming Language Specification Version of August 2, 2023


Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Related Content


Method values

A quick reminder: In today’s live stream, I’ll be deploying a Go app to Kubernetes! I hope you’ll join me! Today we continue the explanation of Method values. There’s nothing too surprising today. The spec mostly just confirms what should seem natural… Method values … As in the discussion of method expressions above, consider a struct type T with two methods, Mv, whose receiver is of type T, and Mp, whose receiver is of type *T.


Method expressions, part 2

Today I’ll continue where I left off yesterday, talking about… Method expressions … Similarly, the expression (*T).Mp yields a function value representing Mp with signature func(tp *T, f float32) float32 The key difference to notice between this example and yesterday’s is that the first argument (that of the receiver) is a pointer here, but was not a pointer in the previous example: func(tv T, a int) int // First argument of type T, not a pointer func(tp *T, f float32) float32 // First argument of type *T, a pointer For a method with a value receiver, one can derive a function with an explicit pointer receiver, so


Method values

As I promised yesterday, today we’re looking at method values, a concept with some similarties to the previous concept of method expressions, but with a bit more utility. Method values If the expression x has static type T and M is in the method set of type T, x.M is called a method value. The method value x.M is a function value that is callable with the same arguments as a method call of x.

Get daily content like this in your inbox!

Subscribe