# Method expressions, part 2

### October 31, 2023

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

``````(*T).Mv
``````

yields a function value representing Mv with signature

``````func(tv *T, a int) int
``````

That is to say, we can get a “pointer” version of the first example if we want to…

``````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
func(tv *T, a int) int         // Now the first argument of type *T, as well
``````

Such a function indirects through the receiver to create a value to pass as the receiver to the underlying method; the method does not overwrite the value whose address is passed in the function call.

That to say, using the `(*T).Mv` construct does not render you suddenly able to change the values of the receiver within the method:

``````type T struct {
a int
}

func (t T) Mv(a int)  { t.a = a } // value receiver
func (t *T) Mp(a int) { t.a = a } // pointer receiver

var t T

fp := (*T).Mp
fp(&t, 4)

fvp := (*T).Mv
fvp(&t, 5)
fmt.Println(t) // Prints 4; value receivers cannot be modified within the method
``````

The final case, a value-receiver function for a pointer-receiver method, is illegal because pointer-receiver methods are not in the method set of the value type.

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