Method values

November 2, 2023

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.M. The expression x is evaluated and saved during the evaluation of the method value; the saved copy is then used as the receiver in any calls, which may be executed later.

type S struct { *T }
type T int
func (t T) M() { print(t) }

t := new(T)
s := S{T: t}
f := t.M                    // receiver *t is evaluated and stored in f
g := s.M                    // receiver *(s.T) is evaluated and stored in g
*t = 42                     // does not affect stored receivers in f and g

The type T may be an interface or non-interface type.

Let’s look at a more complete example:

type Greeter struct {
	Hello string
}

func (g *Greeter) Greet(name string) {
	fmt.Println("%s, %s", g.Hello, name)
}

var english = Greeter{Hello: "Hello"}

english.Greet("Bob") // Prints: Hello, Bob

greet := english.Greet // of type func(string)

greet("Alice") // Prints: Hello, Alice

var spanish = Greetr{Hello: "Hola"}

sauldar := spanish.Greet // of type func(string)

saludar("Roberto") // Prints: Hola, Roberto
saludar("Alicia")  // Prints: Hola, Alicia

This “trick” allows you to treat method values as “normal” functions, to be executed later, or passed around for later use.

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 .