I have this code:
type countHolder struct {
count int
}
func main() {
a := &countHolder{1}
b := *a
a.count = 2
println(b.count)
}
I expected the output to be 2, but the output was 1.
My understanding was that:
a := &countHolder{1}
// a is pointer to struct with data starting at address xb := *a
// b now equals address xa.count = 2
// the struct stored at address x has its count value changed to 2Where am I wrong? is b := *a
creating a copy of the struct?
From the fine specification:
For an operand x of type T, the address operation &x generates a pointer of type *T to x. [...]
For an operand x of pointer type *T, the pointer indirection *x denotes the variable of type T pointed to by x. [...]
That means that the unary &
operator gives you the address of something so a
in:
a := &countHolder{1}
is a pointer. The unary *
operator in:
b := *a
dereferences the pointer a
and leaves you with a countHolder
struct on the right side so b
is a copy of the struct that a
points to. Since b
is a copy of the struct, modifying a.count
:
a.count = 2
(which could also be written as (*a).count = 2
) won't have any affect on b
.
You could also have a look at (https://play.golang.org/p/Zubs8qYBA_K):
func main() {
a := &countHolder{1}
b := *a
fmt.Printf("%T
%T
", a, b)
}
to have a quick look at what types a
and b
are (*counterHolder
and counterHolder
, respectively, in this case).