A blog about programming, Web development, Open Source, Linux and DevOps.

Go - Pointers

A pointer is the memory address of a variable.

Pointers allow us to modify variables indirectly and pass variables to functions by reference rather than by value which allows the functions to modify these variables.

Pointer Type

The pointer type is declared using the * operator followed by the base type (e.g. *int, *[]string).

// Declare a variable of type `*int` (pointer to int).
// The value of an uninitialized pointer is `nil`.
var p1 *int // nil

Generate a Pointer

The address operation &x generates a pointer of type *T to x where T is the type of x.

// A variable is a piece of storage that contain a value.
var x int = 1

// The expression `&x` (address of x) yields a pointer.
var p *int = &x // *int (pointer to int)

fmt.Println(&x) // 0xc00001c030 (memory address)

Derefrencing a Pointer

The expression *p yields the pointer’s underlying value, this is called dereferencing a pointer.

x := 1 // int

p := &x // *int

// Derefrence the pointer to read the underlying value.
y := *p // int

fmt.Println(y) // 1

Derefrencing a nil pointer will cause a run-time panic.

var p *int // nil

*p // Causes a run-time panic

Indirect Variable Modification

With a pointer we can indirectly modify the value of a variable.

x := 1 // int

p := &x // *int

// Set the value of `x` through the pointer `p`.
*p = 2

fmt.Println(x) // 2

Functions Returning a Pointer

A function can safely return the pointer (address) of a local variable.

func f() *int {
  x := 1
  return &x

Functions with Pointer Parameters

A function that accepts a pointer can update the variable indirectly.

func incr(p *int) int {
  *p++      // Increment the value at this address
  return *p // Return the new value