Go Pointers

An introduction to Go pointers

Pointers

A pointer stores the memory address of a variable. As in C, use & to obtain the address of an object and * to access the value referenced by a pointer.

package main

import "fmt"

func main() {
	var a1 int  // define an int variable named a1
	var p1 *int // define a pointer to int named p1

	p1 = &a1  // store the address of a1 in p1
	*p1 = 123 // assign 123 to the referenced value, which is a1

	fmt.Println(a1)
	fmt.Println(p1)
	fmt.Println(*p1)
}

Output:

123
0xc00001c030
123

Passing the value of a variable is called passing by value. Passing a pointer to a variable allows the function to access the referenced variable. Passing by value gives the function only a copy, so it cannot modify the original variable. Passing a pointer allows the function to modify the variable.

package main

import "fmt"

func main() {
	var a1 int = 123
	var a2 int = 123
	fn(a1, &a2)         // pass a1 by value and pass the address of a2
	fmt.Println(a1, a2)
}

func fn(b1 int, b2 *int) {
	b1 = 456
	*b2 = 456
}

Output:

123 456

The . operator accesses a struct field through either a struct value or a pointer to a struct.

package main

import "fmt"

type Person struct {
	name string
	age  int
}

func main() {
	a1 := Person{"devkuma", 23} // create and initialize a Person value
	p1 := &a1                   // store a pointer to a1 in p1
	fmt.Println(a1.name)        // access a field through the value
	fmt.Println((*p1).name)     // access a field through the dereferenced pointer
	fmt.Println(p1.name)        // Go also permits this shorter form
}

Output:

devkuma
devkuma
devkuma

Allocating Memory with new

Use new() to allocate storage dynamically and obtain a pointer to it. Go’s garbage collector automatically releases the allocated storage after it is no longer referenced.

package main

import "fmt"

type Book struct {
	title string
}

func main() {
	bookList := []*Book{}

	for i := 0; i < 10; i++ {
		book := new(Book)
		book.title = fmt.Sprintf("Title#%d", i)
		bookList = append(bookList, book)
	}
	for _, book := range bookList {
		fmt.Println(book.title)
	}
}

Output:

Title#0
Title#1
Title#2
Title#3
Title#4
Title#5
Title#6
Title#7
Title#8
Title#9