【问题标题】:returning value vs pointer in Go constructorGo构造函数中的返回值与指针
【发布时间】:2015-11-19 09:57:39
【问题描述】:

在 go 中构建一个简单的对象时,这些替代方案有什么区别?

func NewGender(value string) Gender {
    return Gender{strings.TrimSpace(value)}
}

func NewGender(value string) *Gender {
    return &Gender{strings.TrimSpace(value)}
}

【问题讨论】:

标签: go constructor pass-by-value


【解决方案1】:

这个问题非常广泛,很大程度上取决于 API 的其余部分。因此,这里只是您在选择一个而不是另一个时可能需要考虑的一些事项(无特定顺序):

  • 不必要的指针会导致 GC 的工作量增加。您可能会通过返回一个指针(一个字)而不是一个结构(零到多个字)来赢得一些时间,但其中一些时间可能稍后会被 GC 扫描消耗掉。

  • 指针也可以表示某事物的存在或不存在,但通常最好使用 comma-ok 习惯用法,否则会返回错误。

  • 说到错误,如果你返回nil有错误,错误被忽略的机会就更小了(因为nil指针取消引用会导致panic)。再说一次,我不认为忽略错误的人是你真正应该考虑的事情。

  • 如果您需要某种形式的跟踪(例如,可以检查构造函数创建的所有实例),则必须返回一个指针,以便检查器可以看到对值的所有更改.

  • 如果大多数类型的方法都有指针接收器,或者 API 中的大多数函数都接受指向类型的指针而不是值,则返回指针更符合人体工程学。

【讨论】:

    【解决方案2】:

    返回的第一项是值,第二项是指针。指针的工作方式与 C 或 C++ 中的指针非常相似,只是它指向的值会像 C# 或 Java 中那样被垃圾收集。 Go 在这两种范式之间提供了某种折衷方案。指针是显式且暴露的,但它仍然是垃圾收集的。这里有一些比较明显的区别;

    1) 如果你将值传递给一个方法或者它是接收者(这通常是令人困惑的),你将无法修改它的值,它将像其他语言中的“按值传递”一样正在修改副本。是的,即使func (g Gender) ChangeGender() 方法也不会改变你调用它的对象的性别。 https://play.golang.org/

    2) 您只能调用为该类型定义的方法。例如,如果你有g *Gender 并且你想调用上面的ChangeGender 方法,你将无法不取消引用你的指针,就像在 C/C++ 中一样。反之亦然。

    3) 按值传递的替代方法是通过引用,您可能知道它是如何工作的,但如果您不知道,我会解释。如果您有一个方法func (g *Gender) ModifyGender() 和一个实例g := &Gender{},那么在调用ModifyGender 时,操作系统字长的指针将作为参数而不是值本身被压入堆栈,并且该方法将使用该地址来修改那里的内存,当控制权返回给调用者时保持更改。如果您的方法适用于具有较大内存占用的对象,这可以极大地提高性能。

    我不会谈论性能。这应该给你足够的信息来考虑它在你的应用程序中是如何工作的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-27
      • 1970-01-01
      • 2015-06-03
      • 1970-01-01
      • 2016-09-28
      • 1970-01-01
      • 2020-06-15
      • 2012-08-07
      相关资源
      最近更新 更多