Pointers in Go – what’s the point? 🤷‍♀️

Pointers in Go – what’s the point? 🤷‍♀️

In any Programming language, whenever a variable or object is created, it is stored in a particular CPU/memory address and when we output the data, it pulls it from that address.

In this article, I will explain what pointers are, its importance, how to declare or initialize a pointer, and using pointers in simple Go programs. To fully understand this article, you should have basic knowledge of a Programming language and the Go syntax.

Introduction

Pointers in Go programming language or Golang are simply variables that store the memory address of other variables. The address is always found in hexadecimal format (starting with 0x, like 0xFFAAF etc.). This might seem tricky at first but it’s quite a simple concept.

Why do we need Pointers?

To understand this, it is important to understand how variables work. A variable is just a convenient name given to a memory location where the data is stored. To access the stored data, the address of that particular memory location is needed. Remembering all the memory addresses in your program in a hexadecimal format can be very tedious, hence, the need for variables to store data with simple names that can be easily remembered and accessed.

A pointer is also referred to as a special kind of variable that is not only used to store the memory address of other variables but also points to where the memory is located and provides ways to find out the value stored at that memory location.

The * and & operators

There are two important operators used while working with pointers.

  • * (asterisk) operator also termed as the dereferencing operator used to declare a Pointer variable and access the value stored in the address.
  • & (ampersand) termed as the address operator used to return the address of a variable or to access the address of a variable to a pointer.

Declaring and Initializing a Pointer

A pointer variable can be created through the normal variable creation process in Go. The only difference is using the operators, for example;

 var name *string

The variable "name" is a pointer that can only store the memory address of string variables. The same applies to other data types such as *int, *float etc. A pointer is initialized with the memory address of another variable using the address operator as shown below;

package main 

import "fmt"

func main () {

// Variable declaration
var count = 50

// Initialization of pointer variable, 'num' with the memory address 
// of the variable 'count'
var num *int = &count

fmt.Println(num)    // This prints the memory address of the variable count
fmt.Println(count)    // This prints the value stored in the variable count
fmt.Println(*num)    // Dereferencing the count variable with the pointer 
// 'num', to get the value in the variable which it points to 
}

/*
Output:
0xc00000a0a0 
50
50
*/

A few points to note about Pointers;

  • The shorthand variable declaration syntax, :=, can also be used to declare and initialize a pointer. The compiler will internally determine the variable is a pointer if an address of a variable is passed to it using the &(address) operator. For example;
a := 5
b := &a

fmt.Println(a)    // This prints the value of a as 5
fmt.Println(b)    // This prints the memory address of a as 0xc00000a0a8
  • Dereferencing a pointer simply means using the * (asterisk) operator before a pointer variable to access the value stored at the variable to which it is pointing. Following up from the previous example;
// Dereferencing a pointer
fmt.Println(*b)    // this also prints 5
  • You can change the value of a pointer at the memory location instead of assigning a new value to the variable. For example;
func main () {
// Changing the value of 'a' by assigning a new value to the pointer 
*b = 12
fmt.Println(a)    // This prints 12, the value of a has been changed 
// from 5 to 12
}
  • The default value, zero-value, or an uninitialized pointer is always nil.
var a *int
fmt.Println(a)    // This prints <nil>
  • Just like variables, pointers can also be passed into functions, structs, to other pointers; that is pointer to pointer. Pointers can also be compared with each other using the comparison operators. == !=
  • Another way to get a pointer is to use the built-in new() function, which takes a type as an argument, allocates enough memory to fit a value of that type, and returns a pointer to it.

A simple Golang program to demonstrate the use of pointers in a function:

// A program that swaps two integers 
// When x = 1, y = 2; swap(x, y) should return x=2 and y=1).
package main

import (
   "fmt"
)

func swap(x, y *int) {
   var change int
   change = *x
   *x = *y
   *y = change
}

func main() {
   x := 10
   y := 100

   fmt.Println("Before swapping; \n x =", x, "\n y =", y)
   swap(&x, &y)
   fmt.Println("After swapping; \n x =", x, "\n y =", y)
}

/*
Output:
Before swapping; 
 x = 10 
 y = 100
After swapping; 
 x = 100 
 y = 10
*/

Conclusion

Hope this gave a good understanding of what pointers are and their usefulness in getting addresses of variables instead of copying a large amount of data every time you need to utilize it.

Note: Pointers are also present in some other programming languages such as C, C++, etc, but not in JavaScript or Python. Python uses objects and referencing.

Thanks for reading! Get creative with pointers and share your thoughts in the comment section below. Also, don’t forget to subscribe to my newsletter to get notified whenever I write new articles.

Resources

golangdocs.com/pointers-in-golang

geeksforgeeks.org/pointers-in-golang/?ref=lbp

callicoder.com/golang-pointers