【发布时间】:2014-06-25 22:00:52
【问题描述】:
在 Go 中有多种方法可以返回 struct 值或其切片。对于我见过的个人:
type MyStruct struct {
Val int
}
func myfunc() MyStruct {
return MyStruct{Val: 1}
}
func myfunc() *MyStruct {
return &MyStruct{}
}
func myfunc(s *MyStruct) {
s.Val = 1
}
我了解这些之间的区别。第一个返回结构的副本,第二个是指向函数内创建的结构值的指针,第三个期望传入现有的结构并覆盖该值。
我已经看到所有这些模式都在各种情况下使用,我想知道关于这些的最佳实践是什么。你什么时候用哪个?例如,第一个可能适用于小型结构(因为开销很小),第二个适用于较大的结构。第三个,如果你想非常节省内存,因为你可以很容易地在调用之间重用单个结构实例。有什么最佳实践来说明何时使用哪个?
同样,关于切片的同样问题:
func myfunc() []MyStruct {
return []MyStruct{ MyStruct{Val: 1} }
}
func myfunc() []*MyStruct {
return []MyStruct{ &MyStruct{Val: 1} }
}
func myfunc(s *[]MyStruct) {
*s = []MyStruct{ MyStruct{Val: 1} }
}
func myfunc(s *[]*MyStruct) {
*s = []MyStruct{ &MyStruct{Val: 1} }
}
再次重申:这里的最佳做法是什么。我知道切片始终是指针,因此返回指向切片的指针没有用。但是,我是否应该返回一个结构值切片、一个指向结构的指针切片,我应该将一个指向切片的指针作为参数传递(Go App Engine API 中使用的模式)?
【问题讨论】:
-
正如你所说,这真的取决于用例。根据情况所有都有效 - 这是一个可变对象吗?我们想要一个副本还是指针?等等。顺便说一句,您没有提到使用
new(MyStruct):) 但是分配指针和返回指针的不同方法之间并没有真正的区别。 -
这简直就是过度工程。结构必须非常大,才能返回指针使您的程序更快。只是不要打扰,编码,配置文件,如果有用就修复。
-
返回值或指针的方式只有一种,即返回值或指针。如何分配它们是一个单独的问题。使用适合您情况的方法,并在担心之前编写一些代码。
-
顺便说一句,出于好奇,我对此进行了基准测试。返回结构与指针的速度似乎大致相同,但是将指针传递给函数的速度要快得多。虽然不在一个水平上,但这很重要
-
@Not_a_Golfer:我认为这只是 bc 分配是在函数之外完成的。基准值与指针的基准测试还取决于结构的大小和事后的内存访问模式。复制缓存行大小的东西是尽可能快的,并且从 CPU 缓存中解引用指针的速度与从主内存中解引用它们的速度大不相同。