2016-11-13 39 views
-1

考虑以下结构的值之间的差异:Golang - 返回一个指针和初始化方法

type Queue struct { 
    Elements []int 
} 

会是什么之间的不同:

func NewQueue() Queue { 
    queue := Queue{} 
    return queue 
} 

func NewQueue() *Queue { 
    queue := &Queue{} 
    return queue 
} 

对我来说,似乎实际上是一样的,(事实上,尝试一些入队和出队的人会得到相同的结果),但我仍然看到两种用法在野外,所以也许更好。

+0

简答:您可以返回,但我认为您通常希望返回您希望人们使用最多的表单。通常,当它是一个像'time.Time'这样的小型类型时,您会返回一个值,否则返回一个指针。在答案中说更详细的内容。 – twotwotwo

回答

2

可以返回一个值,然后调用者调用具有指针接收器的方法。但是,如果调用者总是想要使用指针,因为对象的大或者因为方法需要对其进行适当的修改,您最好还是返回一个指针。 Pointers vs. values is a common question in Go and there's an answer trying to break down when to use one or the other.

在一片支持Queue类型的特定情况下,这是非常小的,快速复制的价值,如果你希望能够到各地复制它,让每个人都看到哪个复制相同的数据被访问的时候,你将需要使用一个指针,因为一个切片实际上是一个开始指针,长度和容量的结构,而当你重新制作或增长它时,切片会发生变化。如果这是一个惊喜,那么在the mechanics of appendslice usage and internals上的Go博客帖子可能是有用的阅读。

如果您的队列不是用于共享或传递,而是在单个函数中本地使用,您可以提供一个append风格的接口,其中操作返回一个已修改的队列,但此时可能只需要use slice tricks directly。如果您的队列同时使用,请认真思考如何使用缓冲通道,这可能不是您想象的那样,但很多棘手的问题已经为您解决了)

另外 - 如果Queue确实添加方法的切片,您可以使它type Queue []int

+0

感谢您的详细回复。我可能会在接下来的几天内增加我的队列,所以我会把它保存为一个结构体。 –

+0

Oops点击发送过快。我不明白的事情是:如果我在上面回来的两种情况有所不同,那么以后的使用情况怎么样呢?也就是说,无论什么'队列'我最终初始化,我用它是一样的,不管它是一个值还是一个指针,这就是为什么我想知道这个区别是否值得。 –

+0

用法不一样; Go隐藏了C++中存在的'.'和' - >'区别,但其他区别仍然存在。例如,在'q:= NewQueue()'之后,要将'q'传递给'func f(q * Queue)',如果'q'是一个值而不是'f(&q) q)'如果它是一个指针。同样,如果你想在全局或类似的地方存储一个'Queue'或者'* Queue',你就不能在指针和值之间没有明确的'&'/'*'。 – twotwotwo