k
is actually an int
pointer data-type, which is *int
. It holds the j
memory address as value when you set it ( at this line:k := &j
).
To access the value from the given pointer, you append the asterisk before a pointer memory address (e.g. a pointer like &j
or &k
) or pointer variable holding the memory address (e.g.: k
). Example:
j := 39
k := &j // k is *int
fmt.Printf("j variable : %v\n", j)
fmt.Printf("j pointer : %v\n", &j)
fmt.Printf("j pointed value : %v\n", *&j)
fmt.Printf("k variable : %v\n", k)
fmt.Printf("k pointer : %v\n", &k)
fmt.Printf("k value's pointed value: %v\n", *k)
fmt.Printf("k pointed value : %v\n", *&k)
You will see that the output is:
j variable : 39
j pointer : 0x414020
j pointed value : 39
k variable : 0x414020
k pointer : 0x40c138
k value's pointed value: 39
k pointed value : 0x414020
Notice that when you access the value of k
memory address: *(&k)
, it returns the value of k
instead.
Playground: Go Playground - The Go Programming Language
So when you change the last printout from fmt.Println(*&j)
to fmt.Println(*&k)
, it simply means:
Access the pointed value given by the k variable's memory address.
This is why you get a memory address instead of a value. To get back the 39
, you change it to *k
,
which says:
Access the pointed value from the given pointer variable's value:
the stored memory address.