My object is not updated even if I use the pointer to a type to update it

go, methods, pointers, slice

Solution

Whenever a method wants to modify the receiver, it must be a pointer to the value; the method must have a pointer receiver.

If a method has a non-pointer receiver, a copy will be made and passed when that method is called. From that point, no matter what you do with the receiver, you can only modify the copy, and not the original.

So in your example:

func (p Person) SetName(newName string)  {
    name := p.GetName();
    *name = newName
}

When `SetName()` is called, a copy is made of the `Person`. Inside `SetName()` you obtain the address of the `name` field of the copy, which you modify. (Actually, a copy of the copy, more on this later...)

Solution: use a pointer receiver:

func (p *Person) SetName(newName string)  {
    name := p.GetName();
    *name = newName
}

From this point on, only `*Person` implements `Individual`, so use a pointer when appending:

individuals = append(individuals, &person)

It's tricky, because after this it sill won't work. Why is that?

It is because the `Person.GetName()` still has a non-pointer receiver:

func (p Person) GetName() *string {
    return &p.name
}

So when `GetName()` is called from `SetName()`, a copy will be made again, and `GetName()` will return the address of the `name` field of the copy, and `SetName()` will only modify the copy created for calling `GetName()`.

So to make all work, you also have to use pointer receiver for `GetName()`:

func (p *Person) GetName() *string {
    return &p.name
}

And now it's working, output (try it on the Go Playground):

{Steve}
&{Peter}
{Peter}

But know that the easiest and recommended way is simply:

func (p *Person) SetName(newName string) {
    p.name = newName
}

That's all it takes.

Problem

I store some `Individual` objects in a slice. Before appending it to the slice I print the name of the `Individual` object. After I have stored it in the slice, I then retrieve it as a pointer and want to change the name to `"Peter"`, but the change does not work since it still prints `"Steve"`. Why? ``` type Individual interface { GetName() *string SetName(name string) } type Person struct { name string } // Implement functions of the Individual interface func (p Person) GetName() *string { return &p.name } func (p Person) SetName(newName string) { name := p.GetName(); *name = newName } var individuals []Individual func main() { person := Person{name: "Steve"} fmt.Println(person) individuals = append(individuals, person) // append Person to slice p1 := individuals[0] // Retrieve the only Person from slice p1.SetName("Peter") // Change name fmt.Println(p1) // Should print "Peter", but prints "Steve" fmt.Println(person) // Should print "Peter", but prints "Steve" } ```

Original source