Reassigning in pointer method receiver

In the first example:

func (s *student) update() {
    s = &student{"unknown", 0}
}

You are assigning an entirely new "pointer value" to s, and the new *s points at a new student value. The variable s is scoped only to the method body, so there are no side effects after this returns.

In the second example

func (s *student) update() {
    *s = student{"unknown", 0}
}

You are dereferencing s, and changing the value of *s to point to a new student value, or to put it differently, you are putting a new student value at the address where s points.


In this example you're changing the address that is stored in s to a different value;

func (s *student) update() {
    s = &student{"unknown", 0}
}

While using a pointer is regarded as 'passing by reference' the reference itself is a value like any other that is pushed onto the call stack. When you return to main, the value of s is whatever it was in that scope. So to give something more concrete, you called main with s = 1 (calling the addresses 1 and 2 for simplicity), in the method you allocate a new student located at address 2 and you set s = 2, when you return that version of s is popped from the stack and the s in main points to 1 which is unchanged.

In this latter example;

func (s *student) update() {
    *s = student{"unknown", 0}
}

You're dereferencing s and assigning a new object to that location, overwriting the existing memory. When you return the pointer in main is still pointing to the same location but you have different data at that location in memory. So in this example you're writing a new student instance to address 1 so when you return you see the new value in the calling scope.

Tags:

Go