【问题标题】:Difference between returning a pointer and a value in initialization methods [duplicate]在初始化方法中返回指针和值之间的区别[重复]
【发布时间】:2017-03-27 09:41:39
【问题描述】:

考虑以下结构:

type Queue struct {
  Elements []int
}

两者有什么不同:

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

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

对我来说,这看起来几乎是一样的,(实际上尝试使用一些入队和出队会产生相同的结果)但我仍然在野外看到这两种用法,所以也许一个更可取。

【问题讨论】:

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

标签: pointers go


【解决方案1】:

可以返回一个值,然后调用者调用具有指针接收器的方法。但是,如果调用者总是想要使用指针,因为对象很大或者因为方法需要就地修改它,那么您不妨返回一个指针。 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 样式接口,其中操作返回修改后的队列,但此时您可能只想@ 987654324@.

(如果您的队列打算同时使用,请认真考虑使用缓冲通道。它可能与您想象的不完全一样,但很多棘手的部分已经由实施者为您解决。)

另外——如果Queue真的是一个添加了方法的切片,你可以将它设为type Queue []int

【讨论】:

  • 感谢您的详细回复。我可能会在接下来的几天里增加我的队列,所以我会保留它作为一个结构。
  • 糟糕,点击发送太快了。我不明白的是:如果我上面返回的两种情况不同,那么之后的用法怎么会一样?也就是说,无论 queue 我最终初始化什么,我都在使用它,不管它是值还是指针,这就是为什么我想知道这种区别是否值得。
  • 用法不一样; Go 隐藏了 C++ 中 .-> 的区别,但其他区别仍然存在。例如,在q := NewQueue() 之后,要将q 传递给func f (q *Queue),如果q 是一个值,则需要使用f(&q);如果是指针,则只需使用f(q)。同样,如果您尝试将 Queue*Queue 存储在全局等中,则无法在没有显式 &/* 的情况下在指针和值之间进行分配。
  • 知道了,这里的关键是区分的隐藏。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-21
  • 2011-12-02
  • 2019-10-04
  • 1970-01-01
相关资源
最近更新 更多