I am having a hard time understanding as to why are these rules associated with method set of pointer type .vs. value type
Can someone please explain the reason (from the interface table perspective)
(Snippet from William Kennedy's blog)
Values Methods Receivers
-----------------------------------------------
T (t T)
*T (t T) and (t *T)
Methods Receivers Values
-----------------------------------------------
(t T) T and *T
(t *T) *T
Snippet from specification
Method sets
A type may have a method set associated with it. The method set of an interface type is its interface. The method set of any other type T consists of all methods declared with receiver type T. The method set of the corresponding pointer type *T is the set of all methods declared with receiver *T or T (that is, it also contains the method set of T). Further rules apply to structs containing anonymous fields, as described in the section on struct types. Any other type has an empty method set. In a method set, each method must have a unique non-blank method name.
The method set of a type determines the interfaces that the type implements and the methods that can be called using a receiver of that type.
*T
you can call methods that have a receiver type of *T
as well as methods that have a receiver type of T
(the passage you quoted, Method Sets).T
and it is addressable you can call methods that have a receiver type of *T
as well as methods that have a receiver type of T
, because the method call t.Meth()
will be equivalent to (&t).Meth()
(Calls).T
and it isn't addressable, you can only call methods that have a receiver type of T
, not *T
.I
, and some or all of the methods in I
's method set are provided by methods with a receiver of *T
(with the remainder being provided by methods with a receiver of T
), then *T
satisfies the interface I
, but T
doesn't. That is because *T
's method set includes T
's, but not the other way around (back to the first point again).In short, you can mix and match methods with value receivers and methods with pointer receivers, and use them with variables containing values and pointers, without worrying about which is which. Both will work, and the syntax is the same. However, if methods with pointer receivers are needed to satisfy an interface, then only a pointer will be assignable to the interface — a value won't be valid.
Here is the answer you must want.
From Golang FAQ:
Why do T and *T have different method sets? From the Go Spec:
The method set of any other named type T consists of all methods with receiver type T. The method set of the corresponding pointer type T is the set of all methods with receiver T or T (that is, it also contains the method set of T). If an interface value contains a pointer *T, a method call can obtain a value by dereferencing the pointer, but if an interface value contains a value T, there is no useful way for a method call to obtain a pointer.
Even in cases where the compiler could take the address of a value to pass to the method, if the method modifies the value the changes will be lost in the caller. As an example, if the Write method of bytes.Buffer used a value receiver rather than a pointer, this code:
var buf bytes.Buffer io.Copy(buf, os.Stdin) would copy standard input into a copy of buf, not into buf itself. This is almost never the desired behavior.
About Golang interface under the hood.