我正在编写一个程序,该程序从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...*/}
现在,我的代码神奇地起作用了。到底是怎么回事?
值接收器对实例的副本进行操作。SecureReader
s
如果该方法改变了实例副本的任何部分(例如Modify s.decrypted
),则一旦该方法退出,它就不会在接收者的原始实例上可见。
随指针接收器而变化,因为该方法将在指针接收器处操作并可以更改实际SecureReader
实例s
,因为指针的副本将传递给该方法。
请参阅“ Golang中的指针与非指针方法接收器不要被咬”中的更多示例。
简而言之:您可以将接收方视为传递给方法的参数。您可能希望按值传递或按引用传递的所有相同原因均适用。
您希望通过引用而不是按值传递的原因:
- 您实际上要修改接收器(“读/写”而不是“读”)
- 结构非常大,深拷贝很昂贵
- 一致性:如果结构上的某些方法具有指针接收器,则其余方法也应如此。这可以预测行为
如果在方法调用中需要这些特征,请使用指针接收器。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句