We know that sending a variable to a function can be a parameter or a pointer. This pointer is usually a data allocation with a certain address. An example can be seen in the program below.
package main
import "fmt"
func zero(xPtr *int) {
*xPtr = 0
}
func main() {
x := 5
zero(&x)
fmt.Println(x)
}
Use *
and &
In Go, a pointer is represented using the character *
(asterisk) followed by the type of the value being stored. In the null function xPtr is a pointer to int.
*
is also used to “dereference” pointer variables. Pointer dereference gives us access to the value that the pointer points to. When we write *xPtr = 0
we are saying “store int 0 in the memory location that xPtr refers to”. If we try xPtr = 0
instead we will get a compiler error because xPtr is not int
but rather *int
, which can only be given another *int
.
Finally we use the &
operator to find the variable address. &x
returns *int
(pointer to int) because x
is an int. This is what allows us to modify the original variable. &x
in main and xPtr in null refer to the same memory location.
Another way to get the pointer is to use the built-in new function:
package main
import "fmt"
func one(xPtr *int) {
*xPtr = 1
}
func main() {
xPtr := new(int)
one(xPtr)
fmt.Println(*xPtr)
}
In some programming languages there is a significant difference between using new
and &
, with great care required to ultimately remove anything created with new
. Go is not like that, because it has garbage collection, that is, memory is cleaned automatically when there is no longer anything to refer to it.