一尘不染

什么时候返回指向结构的指针是一个好主意?

go

我正在学习Go,并且对何时使用指针有些困惑。具体来说,当struct从函数返回a 时,什么时候适合返回结构实例本身,什么时候适合返回指向该结构的指针?

示例代码:

type Car struct {
  make string
  model string
}

func Whatever() {
  var car Car

  car := Car{"honda", "civic"}

  // ...

  return car
}

在什么情况下我想返回一个指针,在什么情况下我 想要?有良好的经验法则吗?


阅读 232

收藏
2020-07-02

共1个答案

一尘不染

您需要牢记两点:性能和API。

如何使用汽车?它是具有状态的对象吗?它是一个大结构吗?不幸的是,当我不知道什么是汽车时,不可能回答。说实话,最好的方法是看看别人在做什么,然后照搬别人。最终,您对这种事情有了感觉。现在,我将描述标准库中的三个示例,并解释为什么我认为它们使用了所做的事情。

  1. hash/crc32:该crc32.NewIEEE()函数返回一个指针类型(实际上是一个接口,但是基础类型是一个指针)。哈希函数的实例具有状态。当您将信息写入哈希时,它会汇总数据,因此当您调用该Sum()方法时,它将为您提供该实例的状态。

  2. time:该time.Date函数返回一个Time结构。为什么?时间就是时间。它没有状态。它就像一个整数,您可以在其中进行比较,对它们进行数学运算等。API设计人员认为,对时间的修改不会更改当前时间,而是会修改一个新时间。作为图书馆的用户,如果我想从现在开始一个月的时间,我想要一个新的时间对象,而不是更改当前的时间对象。时间也只有3个字长。换句话说,它很小,并且使用指针不会提高性能。

  3. math/bigbig.NewInt()是有趣的一个。我们几乎可以同意,当您修改时big.Int,您通常会想要一个新的。A big.Int没有内部状态,那么为什么它是一个指针?答案仅仅是性能。程序员意识到,大智慧很重要。每次进行数学运算时,不断分配可能并不实际。因此,他们决定使用指针,并允许程序员决定何时分配新空间。

我回答了你的问题吗?可能不是。这是一个设计决策,您需要根据具体情况进行解决。在设计自己的库时,我以标准库为指南。实际上,所有这些都取决于判断以及您如何期望客户端代码使用您的类型。

2020-07-02