方法接收器和接口
具有值类型接收器的方法可以被值类型和指针类型调用。
例如,
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"}}
// 值类型变量只能调用 Read 方法
sVals[1].Read()
// 无法编译通过:
// sVals[0].Write("test")
sPtrs := map[int]*S{1: {"A"}}
// 指针类型变量可以调用 Read 和 Write 方法:
sPtrs[1].Read()
sPtrs[1].Write("test")
同理,即使方法是值类型接收器,接口也可以通过指针来满足调用需求。
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
// 无法编译通过, 因为 s2Val 是一个值类型变量, 并且 f 方法不具有值类型接收器。
// i = s2Val
Effective Go 中关于 Pointers vs. Values 写的很棒。