In many previous articles, we have used &
operator when working with the pointer. In today's post, I will explain what it is and when we use it in Golang. To fully understand the pointer, we need to clear &
(ampersand) and *
(wildcard) operator.
Definition of "&" and "*" Operators in GO
The &
 Operator
&
put ahead of a variable when you want to find the memory address of that variable. The &
 operator generates a pointer to its operand.
myInt := 2022
addressMyInt := &myInt
The *
 Operator
*
goes ahead and resolves a variable with a memory address (it is therefore the counterpart to the & operator). It proceeds to obtain the object that the pointer was pointing at, such as: *myInt
myInt := 2022
fmt.Println(*&myInt) // prints 2022
Or we can explicitly declare the variable address:
myInt := 2022
addressMyInt := &myInt
fmt.Println(*addressMyInt) // prints 2022
*
 in front of a Type
When you put the * in front of a type, e.g. *int, it becomes part of the type declaration, it means this variable holds a pointer to an int:
myInt := 2022
var intPointer *int
intPointer = &myInt
Go pointer syntax
The ampersand is used to get/return the memory address of a variable. To make that work, place the &
operator before a variable that stores a value and assigns that to a pointer variable. When accessing the stored value in a pointer, place the *
operator before the pointer variable (this is called dereferencing), and that will return the value the pointer points to as below:
package main
import "fmt"
func main() {
myInt := 2022
var intPointer *int
intPointer = &myInt
fmt.Println("The value of variable:", myInt)
fmt.Println("The address of variable:", intPointer)
fmt.Println("The value under the pointer:", *intPointer)
}
Output:
The value of variable: 2022
The address of variable: 0xc000016088
The value under the pointer: 2022
Example-1: Using the pointer to change the value of the variable
In this example, we will try to change the value of the variable by using a pointer:
package main
import "fmt"
func main() {
myInt := 2022
var intPointer *int
intPointer = &myInt
fmt.Println("Initial value:")
fmt.Println("The value of variable:", myInt)
*intPointer = 19
fmt.Println("After changing:")
fmt.Println("The value of variable:", myInt)
}
Example-2: Get the address of a pointer using the & operator
We can get the address of a pointer using the &
operator as the code shown below:
package main
import "fmt"
func main() {
myInt := 2022
var intPointer *int
intPointer = &myInt
addressOfPointer := &intPointer
fmt.Println("The value of variable:", myInt)
fmt.Println("The address of variable:", intPointer)
fmt.Println("The value under the pointer:", *intPointer)
fmt.Println("The address of pointer:", addressOfPointer)
fmt.Println("The value under the pointer:", **addressOfPointer)
}
Output:
The value of variable: 2022
The address of variable: 0xc000016088
The value under the pointer: 2022
The address of pointer: 0xc00000a028
The value under the pointer: 2022
Example-3: Passing memory locations of variables to a function
In the example below, we will write 2 functions to swap 2 ints. The first function we will parse these 2 ints while the other we will parse the memory locations of these 2 ints as the parameter:
package main
import "fmt"
func main() {
x := 5
y := 6
fmt.Println("Before swap: x=", x, " y=", y)
swap(x, y)
fmt.Println("After swap: x=", x, " y=", y)
swapPointer(&x, &y)
fmt.Println("After swap pointer: x=", x, " y=", y)
}
func swap(x, y int) {
x, y = y, x
}
func swapPointer(x, y *int) {
*x, *y = *y, *x
}
Output:
Before swap: x= 5 y= 6
After swap: x= 5 y= 6
After swap pointer: x= 6 y= 5
We can see that, if you directly the value of x, y will not change if we parse them as parameters because it is passing by value: The value of a function argument is copied to another location in the memory when pass-by-value is used. Within the function, only the copy of the variable is accessed or modified. As a result, the original value is unaffected.
While swapPointer
(x, y *int) takes 2 pointers integer as the parameter. The memory locations of the values are the same as x, y so everything that we do to x, y inside swapPointer
affect x, y values. The final output will swap x and y because of passing by reference.
Summary
Pointers are variables' hexadecimal memory addresses. When working with pointers in Golang, there are two distinct but related notations that can be used. There are symbols *
and &
. The &
simply returns the memory address of the variable.
References
https://en.wikipedia.org/wiki/Pointer_(computer_programming)
go - What is the meaning of '*' and '&'? - Stack Overflow