在具有包含其他结构体的结构体时,我是否应该始终使用指针?

huangapple go评论76阅读模式
英文:

Should I always use pointers when having a struct which contains others structs?

问题

我们有:

type A struct {
  Name  string
  Value string
}

type B struct {
  //
  First  *A
  Second A
}

首先:在B中,使用*A还是A更高效?

其次:当实例化B时,我会使用b := &B{ ... },从而得到一个指向B的指针。所有以B作为接收器的函数都使用func (*B) ...作为签名,因此只对指针进行操作。现在我始终有一个指向B的指针,那么B由什么组成真的重要吗?如果我始终使用指针,无论B有什么字段,我始终传递一个指向B的指针,并且在传递*B时,Second A的值永远不会被复制。或者我有什么遗漏吗?

英文:

We have:

type A struct {
  Name  string
  Value string
}

type B struct {
  //
  First  *A
  Second A
}

First off: What it is more efficient in B, using *A or A?

And second: When instantiating B I would use b := &B{ ... }, and thus have a pointer to B. All functions which have B as receiver use func (*B) ... as signature, therefore operating only on the pointer. Now that I always have a pointer to B, does it really matter what B is composed of? If I always use the pointer, no matter what fields B has, I always pass around a pointer to B and the value of Second A is never copied when passing *B around. Or am I missing something?

答案1

得分: 5

没有一个单一正确的答案。它总是取决于你的使用情况。

一些建议:

  1. 在效率考虑之上,优先考虑语义原因。
  2. A很大时,使用指针。
  3. 当不允许B编辑A时,避免使用指针。

你的第二个陈述是正确的。但是当你有很多B的实例时,如果结构体A的大小明显大于指针的大小,使用指针将更加高效。

如果你有疑问,可以针对使用情况进行测量,然后决定最佳解决方案。

英文:

There is no single right answer. It always depends on your use case.

Some guidance:

  1. Treat semantic reasons over efficiency considerations
  2. Use a pointer when A is "large"
  3. Avoid a pointer when B should not be allowed to edit A

Your second statement is correct. But when you have lots of instances of B using a pointer will be significantly more efficient (if the struct A is significantly bigger than the size of a pointer).

If you are in doubt, measure it for use case and then decide what the best solution is.

答案2

得分: 0

只是想补充一下Sebastian的回答:如果你希望它是nil,请使用*A。有时候这样做会有好处,比如在编组JSON或者与数据库一起使用结构体时。

一个非指针类型的A总是至少具有该类型的零值。所以,即使你没有任何有用的内容,它也会被序列化为JSON。如果只在存在填充的结构体时将其包含在JSON序列化中,将其设置为指针类型,它可以是nil

英文:

Just want to add to Sebastian's answer: use *A if you ever want it to be nil. This has benefits sometimes when marshaling JSON or using the struct with databases.

A non-pointer to a A will always have at least the zero value for that type. So it will always serialize into JSON even if you don't have anything useful there. To include it in the JSON serialization only when a populated struct is present, make it a pointer, which can be nil.

huangapple
  • 本文由 发表于 2014年4月26日 17:33:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/23309042.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定