Receivers and Interfaces
Methods with value receivers can be called on pointers as well as values.
For example,
- type S struct {
- data string
- }
- func (s S) Read() string {
- return s.data
- }
- func (s *S) Write(str string) {
- s.data = str
- }
- sVals := map[int]S{1: {"A"}}
- // You can only call Read using a value
- sVals[1].Read()
- // This will not compile:
- // sVals[1].Write("test")
- sPtrs := map[int]*S{1: {"A"}}
- // You can call both Read and Write using a pointer
- sPtrs[1].Read()
- sPtrs[1].Write("test")
Similarly, an interface can be satisfied by a pointer, even if the method has avalue receiver.
- type F interface {
- f()
- }
- type S1 struct{}
- func (s S1) f() {}
- type S2 struct{}
- func (s *S2) f() {}
- s1Val := S1{}
- s1Ptr := &S1{}
- s2Val := S2{}
- s2Ptr := &S2{}
- var i F
- i = s1Val
- i = s1Ptr
- i = s2Ptr
- // The following doesn't compile, since s2Val is a value, and there is no value receiver for f.
- // i = s2Val
Effective Go has a good write up on Pointers vs. Values.