• 方法接收器和接口

    方法接收器和接口

    具有值类型接收器的方法可以被值类型和指针类型调用。

    例如,

    1. type S struct {
    2. data string
    3. }
    4. func (s S) Read() string {
    5. return s.data
    6. }
    7. func (s *S) Write(str string) {
    8. s.data = str
    9. }
    10. sVals := map[int]S{1: {"A"}}
    11. // 值类型变量只能调用 Read 方法
    12. sVals[1].Read()
    13. // 无法编译通过:
    14. // sVals[0].Write("test")
    15. sPtrs := map[int]*S{1: {"A"}}
    16. // 指针类型变量可以调用 Read 和 Write 方法:
    17. sPtrs[1].Read()
    18. sPtrs[1].Write("test")

    同理,即使方法是值类型接收器,接口也可以通过指针来满足调用需求。

    1. type F interface {
    2. f()
    3. }
    4. type S1 struct{}
    5. func (s S1) f() {}
    6. type S2 struct{}
    7. func (s *S2) f() {}
    8. s1Val := S1{}
    9. s1Ptr := &S1{}
    10. s2Val := S2{}
    11. s2Ptr := &S2{}
    12. var i F
    13. i = s1Val
    14. i = s1Ptr
    15. i = s2Ptr
    16. // 无法编译通过, 因为 s2Val 是一个值类型变量, 并且 f 方法不具有值类型接收器。
    17. // i = s2Val

    Effective Go 中关于 Pointers vs. Values 写的很棒。