在go中构建一个简单的对象时,这些替代方案之间的区别是什么?
func NewGender(value string) Gender {
return Gender{strings.TrimSpace(value)}
}
func NewGender(value string) *Gender {
return &Gender{strings.TrimSpace(value)}
}
答案 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
。字大小将作为参数而不是值本身被推入堆栈,并且该方法将使用该地址来修改那里的内存,当控制返回给调用者时持续更改。如果您的方法可以处理具有大内存占用空间的对象,则可以极大地提高性能。
我不会谈论表演。这应该为您提供足够的信息来考虑它在您的应用程序中的工作方式。