Whether or not the struct contains pointer fields doesn’t matter when choosing struct pointer or value method receivers. Any changes you make to a struct passed by value are “lost” after the function returns (because you’re manipulating a copy of the struct). If that struct contains pointers, then you get a copy of the pointer, so you can modify any data through that pointer.
So in Example 2’s first method, you could do this:
func (s StructOne) method() {
s.id = 1 // pointless because your copy, `s` will be lost after the function returns.
s.user.name = "temporary" // this modifies the data through the s.user pointer.
}
The rest of my answer is just how I think of functions that receive struct values as parameters. Maybe it will be helpful to you or to others:
type A struct {
s string
i int
}
type B struct {
a *A
f float32
}
func FuncA(a A) { }
func FuncB(b B) { }
You could rewrite functions that receive structs as values as functions that receive the individual fields that make up the struct:
func FuncA(s string, i int) { }
func FuncB(a *A, f float32) { }
Notice how when I “unpacked” B
, I kept a *A
as a pointer. Passing structs by value doesn’t cause any sort of recursion where inner struct pointers are also passed by value.
Because a *A
is a pointer, you can modify the fields of a
and those changes will still be there after FuncB
returns.
If you needed to execute methods on your A
struct or B
struct, you could just rebuild the A
or B
as necessary:
func FuncA(s string, i int) {
// do something with the "fields"
data := strings.Repeat(s, i)
// need to execute some other method on A:
A{s: s, i: i}.method()
// do other work...
}
However, if B
's definition was:
type B struct {
a A
f float32
}
Then because the actual A
struct value is embedded into B, you could think of FuncB
also getting A
's fields:
// __________ type B ________
// |___ type A ____ |
// | | |
func FuncB(s string, i int, f float32) {
// maybe I want to build-up my B struct again:
b := B{A{s, i}, f}
}
Then modifying s
or i
would not be persistent after the function returns.