Why when we reference struct using (*structObj)
does Go seem to return a new copy of structObj
rather than return the same address of original structObj
? This might be some misunderstanding of mine, so I seek clarification
package main
import (
"fmt"
)
type me struct {
color string
total int
}
func study() *me {
p := me{}
p.color = "tomato"
fmt.Printf("%p\n", &p.color)
return &p
}
func main() {
p := study()
fmt.Printf("&p.color = %p\n", &p.color)
obj := *p
fmt.Printf("&obj.color = %p\n", &obj.color)
fmt.Printf("obj = %+v\n", obj)
p.color = "purple"
fmt.Printf("p.color = %p\n", &p.color)
fmt.Printf("p = %+v\n", p)
fmt.Printf("obj = %+v\n", obj)
obj2 := *p
fmt.Printf("obj2 = %+v\n", obj2)
}
Output
0x10434120
&p.color = 0x10434120
&obj.color = 0x10434140 //different than &p.color!
obj = {color:tomato total:0}
p.color = 0x10434120
p = &{color:purple total:0}
obj = {color:tomato total:0}
obj2 = {color:purple total:0} // we get purple now when dereference again
Go playground
When you write
obj := *p
You are copying the value of struct pointed to by p
(*
dereferences p
). It is similar to:
var obj me = *p
So obj
is a new variable of type me
, being initialized to the value of *p
. This causes obj
to have a different memory address.
Note that obj
if of type me
, while p
is of type *me
. But they are separate values. Changing a value of a field of obj
will not affect the value of that field in p
(unless the me
struct has a reference type in it as a field, i.e. slice, map or channels. See here and here.). If you want to bring about that effect, use:
obj := p
// equivalent to: var obj *me = p
Now obj
points to the same object as p
. They still have different addresses themselves, but hold within them the same address of the actual me
object.
No, "assignment" always creates a copy in Go, including assignment to function and method arguments. The statement obj := *p
copies the value of *p
to obj
.
If you change the statement p.color = "purple"
to (*p).color = "purple"
you will get the same output, because dereferencing p
itself does not create a copy.
tl;dr Dereferencing (using the *
operator) in Go does not make a copy. It returns the value the pointer points to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With