在Go构造函数中返回值与指针

时间:2015-08-25 15:41:34

标签: go constructor pass-by-value

在go中构建一个简单的对象时,这些替代方案之间的区别是什么?

func NewGender(value string) Gender {
    return Gender{strings.TrimSpace(value)}
}

func NewGender(value string) *Gender {
    return &Gender{strings.TrimSpace(value)}
}

2 个答案:

答案 0 :(得分:10)

问题是一个非常广泛的问题,它在很大程度上取决于您的其他API。所以这里有一些你可能需要考虑的事情,当你选择一个而不是另一个时(无特定顺序):

  • 不必要的指针可以为GC带来更多的工作。你可能会通过返回一个指针(一个单词)而不是一个结构(零到多个单词)赢得一些时间,但有些时间可能会被GC扫描消耗掉。

  • 指针也可以表示某事物的存在与否,尽管通常使用逗号成语更好,或者返回错误。

  • 说到错误,如果你带错误返回nil,错误被忽略的可能性会更小(因为nil指针取消引用会导致恐慌)。再说一遍,我不认为忽视错误的人是你应该考虑的事情。

  • 如果您需要某种形式的跟踪(例如,可以检查构造函数创建的所有实例),则必须返回一个指针,以便检查器可以看到对值的所有更改

  • 如果大多数类型的方法都有指针接收器,或者API中的大多数函数都接受指向类型而不是值的指针,那么返回指针会更符合人体工程学。

答案 1 :(得分:4)

The first item returned is a value, the second is a pointer. The pointer works much like a pointer in C or C++ only the value it points to is garbage collected like in C# or Java. Go offers something of a compromise between those two paradigms. The pointer is explicit and exposed, however it's still garbage collected. Here are a few somewhat obvious differences;

1) If you pass the value to a method or it is the receiver (which is often confusing) you will not be able to modify it's value, it will be a 'pass by value' like in the other languages where you are modifying a copy. Yes, even the method func (g Gender) ChangeGender() will not change the gender of the object you call it on. https://play.golang.org/

2)您只能调用为该类型定义的方法。例如,如果您有g *Gender并且想要调用上面的ChangeGender方法,则无法取消引用指针,就像在C / C ++中一样。相反的情况恰恰相反。

3)传递价值的替代方法是参考,你可能知道它是如何工作的,但万一你不解释。如果你有一个方法func (g *Gender) ModifyGender()和一个实例g := &Gender{},那么当调用ModifyGender时,操作系统的指针就是74 = t 65 = e 73 = s 74 = t 。字大小将作为参数而不是值本身被推入堆栈,并且该方法将使用该地址来修改那里的内存,当控制返回给调用者时持续更改。如果您的方法可以处理具有大内存占用空间的对象,则可以极大地提高性能。

我不会谈论表演。这应该为您提供足够的信息来考虑它在您的应用程序中的工作方式。