Go - Mutability

In Go, only constants are immutable. However because arguments are passed by value, a function receiving a value argument and mutating it, won’t mutate the original value.

package main

import "fmt"

type Artist struct {
    Name, Genre string
    Songs       int
}

func newRelease(a Artist) int {
    a.Songs++
    return a.Songs
}

func main() {
    me := Artist{Name: "Matt", Genre: "Electro", Songs: 42}
    fmt.Printf("%s released their %dth song\n", me.Name, newRelease(me))
    fmt.Printf("%s has a total of %d songs", me.Name, me.Songs)
}

Output:

Matt released their 43th song
Matt has a total of 42 songs

As you can see the total amount of songs on the me variable’s value wasn’t changed. To mutate the passed value, we need to pass it by reference, using a pointer.

package main

import "fmt"

type Artist struct {
    Name, Genre string
    Songs       int
}

func newRelease(a *Artist) int {
    a.Songs++
    return a.Songs
}

func main() {
    me := &Artist{Name: "Matt", Genre: "Electro", Songs: 42}
    fmt.Printf("%s released their %dth song\n", me.Name, newRelease(me))
    fmt.Printf("%s has a total of %d songs", me.Name, me.Songs)
}

The only change between the two versions is that newRelease takes a pointer to an Artist value and when I initialize our me variable, I used the & symbol to get a pointer to the value.

Another place where you need to be careful is when calling methods on values as explained a bit later.

http://www.golangbootcamp.com/book/basics#sec-pointers


See also