Go Pointers Demystified: An In-Depth Look

Ambiyansyah Risyal
4 min readDec 25, 2022

--

Go Pointers Demystified: An In-Depth Look
Photo by Mario Gogh on Unsplash

Go pointers are often a source of confusion for new Go programmers, but they are actually a powerful and important feature of the language. In this article, we will demystify Go pointers and take an in-depth look at how they work and how to use them effectively in your Go programs.

First, let’s start by defining what a pointer is. In general, a pointer is a reference to a memory location in a computer’s memory. When you create a variable in Go, the value of that variable is stored in a specific memory location. A pointer is simply a way to reference that memory location, rather than the value stored at that location.

One of the key benefits of pointers is that they allow you to pass large data structures or objects to functions without having to make copies of them. This can save both time and memory, especially when working with large data structures.

To create a pointer in Go, you use the & operator to get the memory address of a variable. For example:

package main

import "fmt"

func main() {
x := 10
ptr := &x
fmt.Println(ptr)
}

In this example, we create a variable x with the value 10, and then create a pointer ptr to x using the & operator. When we print ptr, we will see the memory address of x.

To access the value stored at a memory location referenced by a pointer, we use the * operator. This is known as dereferencing the pointer. For example:

package main

import "fmt"

func main() {
x := 10
ptr := &x
fmt.Println(*ptr)
}

In this example, we dereference the pointer ptr to access the value stored at the memory location it references. When we run this program, it will print 10.

It’s important to note that pointers are not just limited to simple types like integers. You can also create pointers to other data types, such as structs and arrays. For example:

package main

import "fmt"

type Person struct {
Name string
Age int
}

func main() {
p := Person{Name: "John", Age: 30}
ptr := &p
fmt.Println(*ptr)
}

In this example, we create a struct Person with a name and an age, and then create a pointer ptr to an instance of that struct. When we dereference the pointer and print it, we will see the entire struct printed out.

Pointers are also useful when you want to modify the value of a variable from within a function. For example:

package main

import "fmt"

func double(x *int) {
*x = *x * 2
}

func main() {
x := 10
double(&x)
fmt.Println(x)
}

In this example, we create a function double that takes a pointer to an integer as an argument. Inside the function, we dereference the pointer and multiply the value by 2. When we call the double function and pass it the memory address of x using the & operator, the value of x is doubled to 20.

It’s also worth noting that Go has a special type of pointer called a nil pointer. A nil pointer is a pointer that does not point to any memory location. It's important to check for nil pointers when working with pointers in Go, as attempting to dereference a nil pointer will result in a runtime error.

Another important concept to understand when working with pointers in Go is the difference between passing a value and passing a reference. When you pass a value to a function, a copy of that value is made and passed to the function. This means that any changes made to the value within the function have no effect on the original value outside of the function.

On the other hand, when you pass a reference to a value, you are passing a pointer to the memory location where the value is stored. This means that any changes made to the value within the function will be reflected in the original value outside of the function.

Here’s an example to illustrate the difference between passing a value and passing a reference:

package main

import "fmt"

func doubleValue(x int) {
x = x * 2
}

func doubleReference(x *int) {
*x = *x * 2
}

func main() {
x := 10
doubleValue(x)
fmt.Println(x) // prints 10

doubleReference(&x)
fmt.Println(x) // prints 20
}

In this example, we have two functions: doubleValue and doubleReference. The doubleValue function takes an integer as an argument and doubles it within the function, but the original value of x is not changed because a copy of the value is passed to the function.

On the other hand, the doubleReference function takes a pointer to an integer as an argument and doubles the value at the memory location it references. When we pass the memory address of x to the doubleReference function using the & operator, the original value of x is doubled to 20.

In conclusion, pointers are a powerful and important feature of Go that allow you to work with memory references and pass large data structures or objects to functions efficiently. They may seem intimidating at first, but with a little practice and understanding, they can become a valuable tool in your Go programming toolkit.

--

--

Ambiyansyah Risyal
Ambiyansyah Risyal

Written by Ambiyansyah Risyal

Software engineer. Lover of learning and creating. Sharing thoughts and experiences on tech and software development. Always seeking new ideas and techniques.

No responses yet