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 typeT
andM
is in the method set of typeT
,x.M
is called a method value. The method valuex.M
is a function value that is callable with the same arguments as a method call ofx.M
. The expressionx
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