何时返回指向结构的指针是个好主意?

时间:2012-06-11 20:13:50

标签: pointers go

我正在学习Go,而且我对何时使用指针感到有点困惑。具体来说,从函数返回struct时,何时返回结构实例本身是合适的,何时返回指向结构的指针是适当的?

示例代码:

type Car struct {
  make string
  model string
}

func Whatever() {
  var car Car

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

  // ...

  return car
}

我想要返回指针的情况是什么,以及想要的地方?有一个很好的经验法则吗?

3 个答案:

答案 0 :(得分:14)

您需要记住两件事,即性能和API。

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

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

  2. timetime.Date函数返回Time结构。为什么?时间是一个时间。它没有国家。它就像一个整数,你可以比较它们,在它们上预先形成数学等等.API设计师决定对时间进行修改不会改变当前时间而是创建一个新时间。作为图书馆的用户,如果我想从现在开始一个月的时间,我会想要一个新的时间对象,而不是改变我现有的时间对象。时间也只有3个字。换句话说,它很小,使用指针不会有性能提升。

  3. math/bigbig.NewInt()是一个有趣的问题。我们非常同意当您修改big.Int时,您通常会想要一个新的big.Int。 {{1}}没有内部状态,为什么它是指针?答案就是表现。程序员意识到大赌注......很大。每次进行数学运算时不断分配可能不切实际。因此,他们决定使用指针并允许程序员决定何时分配新空间。

  4. 我已回答你的问题吗?可能不是。这是一个设计决策,您需要根据具体情况来确定。我在设计自己的库时使用标准库作为指导。这完全取决于判断以及您希望客户端代码如何使用您的类型。

答案 1 :(得分:2)

通常,当你想模仿一个面向对象的样式时,你有一个“对象”来存储可以改变对象的状态和“方法”,那么你将有一个“构造函数”函数返回指向结构(将其视为与其他OO语言一样的“对象引用”)。 Mutator方法必须是指向结构类型的方法而不是结构类型本身的方法,以便更改“对象”的字段,因此有一个指向结构而不是结构的指针很方便值本身,以便所有“方法”都在其方法集中。

例如,在Java中模仿这样的东西:

class Car {
  String make;
  String model;
  public Car(String myMake) { make = myMake; }
  public setMake(String newMake) { make = myMake; }
}

你经常会在Go中看到类似的东西:

type Car struct {
  make string
  model string
}
func NewCar(myMake string) *Car {
  return &Car{myMake, ""}
}
func (self *Car) setMake(newMake string) {
  self.make = newMake
}

答案 2 :(得分:1)

非常糟糕,在特定情况下可能会出现例外情况:

  • 当它真的很小(不超过几个单词)时返回一个值。
  • 当复制开销严重影响性能时(大小是很多单词),返回一个指针。