Understanding pointer in golang
Ken Aqshal Bramasta / October 25, 2022
6 min read • ––– views
So, what is a pointer?
Pointer is the variable type in golang that contain memory address to become a reference rather than the value itself. imagine that you have variable called nickname
that has value Ken
, so the pointer is stored memory address where value Ken
is being saved with hexadecimal format that have prefix 0x
like 0xc000010250
.
Every pointer variable has a *
(asterisk) symbol before the data type when declared the variable with nil
as a default value.
1var nickname *string
And it would help if you remembered that the pointer variable could not store a value that is not a pointer or vice versa because the pointer variable has a hexadecimal format in-store the memory address.
Suppose you are wondering why there's a pointer in golang. In that case, the pointer is suitable for torturing developers computation speed since it's just a "number" that has a small size if it compares to the actual value.
How to use it?
Ok, so before you start to use pointer in golang, there's something that you must know before
- You can get pointer values in regular variables by adding an ampersand (
&
) right before the variable name. The name of this method isreference
. - Vice versa, you can get the original value of a pointer variable by using an asterisk(
*
) right before the variable name. This method is calleddereference
.
So let's jump into the example
1package main
2
3import "fmt"
4
5func main() {
6 var nicknameA string = "Ken"
7 var nicknameB *string = &nicknameA
8
9 fmt.Println("nicknameA (value) :", nicknameA)
10 fmt.Println("nicknameA (memory address) :", &nicknameA) //referencing
11 fmt.Println("nicknameB (value) :", *nicknameB) //derefencing
12 fmt.Println("nicknameB (memory address) :", nicknameB)
13}
If you run this in terminal, it will be like this
we have nicknameA
as a regular variable and nicknameB
as a pointer, so we have two variables that contain the same memory address at the same time. that's why when you print value of nicknameA
and dereference variable nicknameB
it will be print the same value
And you can also take a look at the memory address where the value is being stored with print nicknameB
, which is the pointer variable, and dereferencing of variable nicknameA
so that you will get the pointer value (with hexadecimal format)
Is there any effect when we change the value?
As I mentioned, that pointer only stores a memory address
. So when there are one or more pointer variables that contain memory address to the regular variable, if there's a change in the value of the regular variable, all pointer variables that have address to the regular variable will take effect to change the value when the pointer is being dereferenced
let's take a look in an example
1package main
2
3import "fmt"
4
5func main() {
6 var nicknameA string = "Ken"
7 var nicknameB *string = &nicknameA
8
9 fmt.Println("Before change value")
10 fmt.Println("nicknameA (value) :", nicknameA)
11 fmt.Println("nicknameA (memory address) :", &nicknameA)
12 fmt.Println("nicknameB (value) :", *nicknameB)
13 fmt.Println("nicknameB (memory address) :", nicknameB)
14
15 nicknameA = "Bram"
16
17 fmt.Println("\nAfter change value")
18 fmt.Println("nicknameA (value) :", nicknameA)
19 fmt.Println("nicknameA (memory address) :", &nicknameA)
20 fmt.Println("nicknameB (value) :", *nicknameB)
21 fmt.Println("nicknameB (memory address) :", nicknameB)
22}
If you take try to run it in terminal, it will be like this
As you see, the nicknameB
stores the address from nicknameA
. So when nicknameA
changes, the value of deferencing nicknameB
will follow the actual value of nicknameA
. and the memory address it's still remain same because you change the value not the address
Pointer in parameter
pointer can be used as parameter in function. all you have to do is add an asterisk(*
) before the definition of data type of the parameter, the same way you define the pointer variable. and you can also use referenceing
and dereferencing
too inside the function. but keep in mind if you want to change the actual value of the pointer variable, you have to dereference
in the left assignment like this
1func replace(old *string, new string) {
2 *old = new
3}
so let's just take a look at an example on how to use pointer as a parameter
1package main
2
3import "fmt"
4
5func replace(old *string, new string) {
6 *old = new
7}
8
9func main() {
10 var word string = "Ken"
11 fmt.Println("before:", word)
12
13 replace(&word, "Bramasta")
14 fmt.Println("after:", word)
15}
You will create a function with two parameters, the first is old
as a pointer variable, and the second is new
as a regular variable. The logic inside the function will replace the old
value that is already being dereferenced in the left argument with the new one new
parameter. if you try to run this in the terminal, it should be like this
now we have successfully modified the value of a variable that exists outside of a function
Still confused about it?
Ok, so if you're unfamiliar with the pointer concept, you will still have doubt in your head. But you will get used to it over time when using pointers, and I will give you a comparison to another language that doesn't have a pointer concept, like javascript
In javascript when we want to change the value of the variable through the logic inside the function, we can make it with a defined variable that will contain the return from the function like this
1let counting = (counter) =>{
2 counter += 1
3 return counter
4}
5
6let counter = 1
7counter = counting(counter)
When you run this, it will return 2, and I think this is the only way to change the variable value through logic inside the function. But different with golang, you can do it in two ways. the first one is just like in the JS
1package main
2
3import "fmt"
4
5func counting(counter int) int {
6 counter += 1
7 return counter
8}
9
10func main() {
11 var count int = 1
12 count = counting(count)
13 fmt.Println(count)
14}
But you can also do that by using the pointer as a parameter to change variable value through the logic inside the function without returning the value.
1package main
2
3import "fmt"
4
5func counting(counter *int) {
6 *counter += 1
7}
8
9func main() {
10 var count int = 1
11 counting(&count)
12 fmt.Println(count)
13}
Recap
- You can define the pointer variable by adding an asterisk(
*
) before the data type - Pointer can be used as a parameter in a function
- Ampersand(
&
) on the regular variable willreference
memory address of the value - Asterisk(
*
) on the pointer variable willdereference
the original value - Pointer can be used to modify the value that exists outside the function
Enjoyed this post?
Check out some of my other articles: