Frequently Asked Questions: 我的方法应该定义在值还是指针上?

这是我参与更文挑战的第12天,活动详情查看:更文挑战

func (s *MyStruct) pointerMethod() { } // method on pointer
func (s MyStruct)  valueMethod()   { } // method on value
复制代码

对于不熟悉指针的程序员来说,这两个例子之间的区别可能会令人困惑,但情况实际上非常简单。 在类型上定义方法时,接收器(上述示例中的s)的行为就像是该方法的参数一样。 是否将接收器定义为值或指针考虑的东西是一样的。那么作为函数参数是否应为值或指针。 有以下几个考虑因素。

第一,也是最重要,该方法是否需要修改接收器中的属性值? 如果是,那么接收器必须是指针。 (可以参考切片和map,为了改变一个切片的长度,它的接收者必须是指针。)如果PointerMethod修改了s的属性,方法调用方将看到这些更改,但是对于Valuemethod(这是传递值的定义)因为传递的是s的拷贝副本,因此它使得它所做的更改对于调用方是不可见的。

顺便提一句,Java中的方法接受器都是指针,虽然是隐式的。在Go中,传递值是比较少见的。

第二,考虑到效率,如果接收器很大的话,比如一个巨大的struct实例,使用指针的成本就会低得多得多。

第三,因为要保证一致性,如果有的方法一定要使用指针接收器,那么其他方法也必须保持一致,都是用指针接收器。详细的可以看golang.org/doc/faq#dif… 这篇文章。

当然了,对于一些基本数据类型,切片,很小的结构体,使用值来做接收器是比较合理的。总体来说,如果你的语义还有使用场景要求你使用指针,那么你就需要使用真正,其他的情况如果不是特别大的值,使用值来作为接收器相对比较清晰和高效。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享