ZetCode

Go pointer

last modified December 12, 2020

Go pointer tutorial shows how to work with pointers in Golang language.

A pointer holds the memory address of a value. The zero value of a pointer is nil. Unlike in C language, Go has no pointer arithmetic.

Pointers are useful when we copy large structures or when we want to modify data in a different function.

var pv *int = &mysum

The *int is a pointer to an integer value. The & is used to get the address (a pointer) to the variable.

fmt.Println(*pv)

The * character is used to dereference a pointer -- it returns a value to which the pointer references.

Go pointer example

The following is a simple pointer example in Go.

simple.go
package main

import "fmt"

func main() {

    var count int = 4
    fmt.Println(count)

    var pv = &count
    *pv = 3
    fmt.Println(pv)
    fmt.Println(*pv)

    var pv2 *int = &count
    *pv = 2
    fmt.Println(pv2)
    fmt.Println(*pv2)

    pv3 := &count
    *pv = 1
    fmt.Println(pv3)
    fmt.Println(*pv3)
}

We define a count integer variable. We create three pointers to the variable, using three different forms.

var count int = 4

We create the count variable.

var pv = &count

We create a pointer to the count variable.

*pv = 3

Via the pointer dereference, we modify the value of count.

fmt.Println(pv)
fmt.Println(*pv)

We print the address and the value of the pv pointer.

$ go run simple.go 
4
0xc0000140f8
3
0xc0000140f8
2
0xc0000140f8
1

Go pointer modify

Pointers can be used to modify variables outside of their defining function.

modify.go
package main

import "fmt"

func modify(pv *int) {

    *pv = 11
}

func main() {

    var count int = 10
    fmt.Println(count)

    modify(&count)
    fmt.Println(count)
}

Inside the main function, we define the count variable. The modify function takes a pointer as a parameter. We can use it to modify the count variable outside the main function. By default, a function in Go passes variables by value.

$ go run modify.go 
10
11

Go pointer to struct

Pointers are often used with structures in Go.

pstruct.go
package main

import "fmt"

type User struct {
    name       string
    occupation string
}

func modify(pu *User) {

    pu.name = "Robert Roe"
    pu.occupation = "driver"
}

func main() {

    u := User{"John Doe", "gardener"}
    fmt.Println(u)

    modify(&u)

    fmt.Println(u)
}

We have a User structure. We change the structure inside the modify function through a pointer.

pu.name = "Robert Roe"

The pu.name is the same as (*pu).name.

$ go run pstruct.go 
{John Doe gardener}
{Robert Roe driver}

Go pointer with new keyword

The new keyword takes a type as an argument, allocates enough memory to fit a value of that type and returns a pointer to it.

newkey.go
package main

import (
    "fmt"
    "reflect"
)

type User struct {
    name       string
    occupation string
}

func main() {

    var pu *User = new(User)
    fmt.Println(pu)
    fmt.Println(reflect.TypeOf(pu))

    pu.name = "Robert Roe"
    pu.occupation = "accountant"
    fmt.Println(pu)
}

In the example, we create a user with the new keyword.

$ go run newkey.go 
&{ }
*main.User
&{Robert Roe accountant}

Go pointer to pointer

A pointer can point to another pointer. To dereference a value of such a pointer, we use the ** characters.

pointer2pointer.go
package main

import "fmt"

func main() {

    var a = 7
    var p = &a
    var pp = &p

    fmt.Println(a)
    fmt.Println(&a)

    fmt.Println("--------------------")

    fmt.Println(p)
    fmt.Println(&p)

    fmt.Println("--------------------")

    fmt.Println(pp)
    fmt.Println(&pp)

    fmt.Println("--------------------")

    fmt.Println(*pp)
    fmt.Println(**pp)
}

The example creates a pointer pp to another pointer p.

$ go run pointer2pointer.go 
7
0xc0000140f8
--------------------
0xc0000140f8
0xc00000e028
--------------------
0xc00000e028
0xc00000e030
--------------------
0xc0000140f8
7

In this tutorial, we have covered Go pointers.

List all Go tutorials.