英文:
golang: return a pointer or pass a reference
问题
构建一个对象的最佳方法是什么?
让我写一些代码:
type Car struct {
Wheels int
Doors int
}
这些汽车以某种方式存储在某个地方。那么我的接口应该是这样的类型:
func (s Store) GetCar() *Car
还是应该这样做:
func (s Store) GetCar(*Car)
并传递一个变量的引用?
我正在寻找一些经验法则。
谢谢!
英文:
What is the best way to "build" an object.
Leme write some code:
type Car struct {
Wheels int
Doors int
}
This cars are stored somewhere, somehow. So should my interface be the type of
func (s Store) GetCar() *Car
or should I make it
func (s Store) GetCar(*Car)
and pass a reference to a variable?
Im looking for some sort of rule of thumb.
Thanks!
答案1
得分: 17
Go管理堆/栈,跟踪引用何时超出作用域。因此,您可以放心地返回指针。
func (s *Store) GetCar() *Car {
return &Car{Store: s}
}
英文:
Go manages the heap/stack, keeping track when the reference goes outside of scope. So, you can return the pointer without any worries.
func (s *Store) GetCar() *Car {
return &Car{Store: s}
}
答案2
得分: 14
在许多情况下,这种方式更可取:
func (s Store) GetCar() *Car
因为它更方便和可读,但也有一些后果。所有的变量,比如Car
,都是在函数内部创建的,这意味着它们被放置在堆栈上。在函数返回后,这段堆栈上的内存被标记为无效,并且可以再次使用。对于指针值(如*Car
),情况略有不同。因为指针实际上意味着你想与其他作用域共享该值并返回一个地址,所以该值必须存储在某个地方,以便在调用函数时可用。它被复制到堆内存中,并在垃圾回收找不到对它的引用时保留在那里。
这意味着有一些开销:
- 从堆栈复制值到堆
- 垃圾回收的额外工作
如果值相对较小,这些开销并不显著。这就是为什么我们必须在io.Reader
和io.Writer
中传递参数,而不是在返回值中拥有该值的原因。
如果你想深入了解,请参考以下链接:
Language Mechanics On Stacks And Pointers
和
Bad Go: pointer returns
英文:
In many cases this is preferable
func (s Store) GetCar() *Car
because it is more convenient and readable, but has consequences. All variables such as Car
are created inside the function which means they are placed onto stack. After function return this memory of stack is marked as invalid and can be used again. It a bit differs for pointer values such as *Car
. Because pointer is virtually means you want to share the value with other scope and return an address, the value has to be stored somewhere in order to be available for calling function. It is copied onto heap memory and stays there until garbage collection finds no references to it.
It implies overheads:
- copying values from stack to heap
- additional work for garbage collection
The overheads is not significant if the value is relatively small. This is a reason why we have to pass an argument in io.Reader
and io.Writer
rather than have the value in return.
If you'd like to dive yourself into guts follow the links:
Language Mechanics On Stacks And Pointers
and
Bad Go: pointer returns
答案3
得分: 5
最常见的方法是将其写成:
func (s Store) GetCar() *Car
或者,如果你不想使用指针,可以这样写:
func (s Store) GetCar() Car
另一种选择是将其写成GetCar(aCar *Car)
,这可能有效,但不够清晰,因为不明显aCar
应该为空,然后由函数填充。
英文:
The most common way to do that would be to write it as:
func (s Store) GetCar() *Car
Or, if you don't want to use pointers, you can do it like:
func (s Store) GetCar() Car
The other alternative, making it GetCar(aCar *Car)
might work, but it will not be as clear since it's not obvious that aCar
should be sent empty and then populated by the function.
答案4
得分: -1
从一开始就使用new在堆上创建它们。
英文:
Create them on heap from beginning by new.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论