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.