指针和值接收器类型有什么区别?

时间:2015-04-05 19:17:36

标签: go

我正在编写一个程序,它从io.Reader读取数据并将它们缓存在bytes.Buffer中。

type SecureReader struct {
    pipe      io.Reader
    shared    *[32]byte
    decrypted bytes.Buffer
}

func (s SecureReader) Read(b []byte) (int, error) {
    s.decryptPipeIntoBuffer()
    return s.decrypted.Read(b)
}

func (s SecureReader) decryptPipeIntoBuffer() (int, error) {/*Lots of code...*/}

我首先使用了值接收器,因为我认为它们是相同的。但是,我注意到我的方法在调用时没有做任何事情:SecureReader.Read()总是返回io.EOF。

我撞了一下头,将接收器类型更改为

func (s *SecureReader) decryptPipeIntoBuffer() (int, error) {/*Lots of code...*/}

现在我的代码神奇地工作了。发生了什么事?

1 个答案:

答案 0 :(得分:3)

值接收器在SecureReader实例s副本上运行。

如果方法改变了实例的 copy 的任何部分(如修改s.decrypted),则一旦方法退出,它就不会在接收器的原始实例上可见。< / p>

使用指针接收器进行更改,该方法操作并可以改变实际的SecureReader实例s,因为指针的 copy 被传递给方法。


请参阅“Don't Get Bitten by Pointer vs Non-Pointer Method Receivers in Golang”中的更多示例。

  

简单地说:您可以将接收器视为传递给方法的参数。您可能希望通过值传递或通过引用传递的所有相同原因都适用。

     

您希望通过引用传递而不是按值传递的原因:

     
      
  • 您想要实际修改接收器(“读/写”而不是“读”)
  •   
  • 结构非常大,深拷贝很贵
  •   
  • 一致性:如果struct上的某些方法有指针接收器,其余的也应该如此。这允许行为的可预测性
  •   
     

如果在方法调用中需要这些特性,请使用指针接收器。