Understanding pointer in golang

Ken Aqshal Bramasta

Ken Aqshal Bramasta / October 25, 2022

6 min read––– views

Ken Aqshal Bramasta

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 is reference.
  • Vice versa, you can get the original value of a pointer variable by using an asterisk(*) right before the variable name. This method is called dereference.

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 will reference memory address of the value
  • Asterisk(*) on the pointer variable will dereference 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:

  1. Debugging Dockerized Go Applications with VS Code
  2. How To Connect Multiple Database With Node JS and Prisma
  3. Race condition on state react.js