我应该用指向结构的指针还是仅仅在结构上定义我的func?

时间:2016-03-15 18:53:59

标签: pointers go function-pointers

在我看来,我似乎有两个选择:

foo := Thing{}
foo.bar()

foo := &Thing{}
foo.bar()


func (self Thing) bar() {
}

func (self *Thing) bar() {
}

使用self Thing或self * Thing定义我的funcs的更好方法是什么?

编辑:这不是关于方法和功能的问题的重复。这个问题与Thing和& Thing有关,我认为这与它自己的网址有所不同。

2 个答案:

答案 0 :(得分:2)

the official FAQ

查看此项目
  

对于不习惯指针的程序员来说,区别   这两个例子可能令人困惑,但事实上情况确实如此   非常简单。在类型上定义方法时,接收器(在   上面的例子)就像它是一个参数一样   方法。是将接收器定义为值还是指针   同样的问题,那么,函数参数是否应该是a   值或指针。有几点需要考虑。

     

首先,最重要的是,该方法是否需要修改   接收器?如果是,接收器必须是指针。 (切片和地图   作为参考,所以他们的故事更微妙,但是   在接收器必须的方法中更改切片长度的实例   仍然是一个指针。)在上面的例子中,如果pointerMethod修改   在s的字段中,调用者将看到这些更改,但valueMethod是   用调用者的参数的副本调用(这是#的定义)   传递一个值,所以改变它使得调用者看不见。

     

顺便说一句,指针接收器与Java中的情况相同,   虽然在Java中,指针隐藏在封面下;它的Go's   价值接收器是不寻常的。

     

其次是效率的考虑。如果接收器很大,a   例如,大结构,使用指针要便宜得多   接收机。

     

接下来是一致性。如果该类型的某些方法必须具有   指针接收器,其余的也应该是,所以方法集是   无论使用何种类型,都是一致的。请参阅有关的部分   方法设置细节。

     

对于基本类型,切片和小结构等类型,值   接收器非常便宜,所以除非方法的语义要求   一个指针,一个值接收器是高效和清晰的。

答案 1 :(得分:1)

没有明确的答案,但它们完全不同。当你没有使用指针时,你会通过值'这意味着你调用它的对象将是不可变的(修改副本),当你使用指针时你通过引用传递#39;。我会更频繁地说你使用指针变种,但它完全是情境化的,没有更好的方法。

如果你看一下各种编程框架/类库,你会看到很多例子,作者故意选择按价值或参考做事。例如,在C#.NET中,这是结构和类之间的根本区别,像GuidDateTime这样的类型被故意实现为结构(值类型)。同样,我认为指针通常是更好的选择(如果你看一下.NET几乎所有东西都是类,引用类型),但它肯定取决于你希望用类型和/或你想要的消费者实现什么/其他开发人员与之互动。您可能需要考虑性能和并发性(也许您希望所有内容都符合价值,因此您不必担心类型上的并发操作,也许您需要一个指针,因为对象内存占用很大并且复制它会使你的程序太慢或耗费。)