Kiril
Kiril

Reputation: 6219

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

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?

Upvotes: 1

Views: 231

Answers (2)

Matt
Matt

Reputation: 23729

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.

Upvotes: 0

Sebastian
Sebastian

Reputation: 17413

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.

Upvotes: 5

Related Questions