A Simple Friendly Story of Go Pointers
Scary stories have been told about the pointers in C/C++. The pointers in Go, however, are just simple and friendly: two usages of the asterisk operator, one usage of the ampersand operator, and you have it.
Let’s see them in the life story of variables a
, b
, c
, and d
.
a := 42
2. b
would also like to share the precious value with a
b := a
3. Then there is c
, who does not want to hold an integer value, but the address of an integer variable
The first usage of the asterisk operator: when put in front of a type, it denotes that the pointer only points to variables of that particular type
var c *int
The usage of the ampersand operator: when put in front of a variable, it returns the address of that variable
c = &a
4. Now we have a back door to access a
The second usage of the asterisk operator: when put in front of a pointer, it returns the variable living in the address that pointer represents
*c // This basically gives us the variable a
5. Changing the value of b
has no effect on a
, since the only relationshipb
had with a
is just having copied its value once
b = 43 // variable a still has the value 42
6. However, sincec
knows where a
lives, with c
we can do whatever we want to a
*c = 44 // now variable a's value is set to 44, no longer the answer to the ultimate question...
7. What’s more, let variable d
copy the value of c
so that we have two *int
variables who know where a
lives
d := c
8. Now with *d
we also have total control over (the poor) a
*d = 45 // now both a and *c give back 45
Go pointers are themselves variables. Two pointers pointing to the same address (like c
and d
) are still totally independent, each occupies its own address in the memory. The most confusing C++ situation of the same memory being represented by multiple aliases, or references variables, is not going to happen in Go.
Another tempting idea is, whether pointers to different types are assignable to each other — since they all store memory addresses. The answer is “no”, even for underlying types:
type i intvar a ia = 1var b *intb = &a // You can't do this!