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