Methods don't change the value of the parent struct

Issue

I’ve got a question about structs & methods. I tried creating a method that changes the value inside an array of the receiver/parent struct. Inside the method, the value of the reveiver’s matrix changes, but it doesn’t change on the main.

type Play struct {
    Matrix [4][4]int
}

func (p Play) Randomize() {
    p.Matrix[1][3] = 2
    fmt.Println(p.Matrix[1][3])
    fmt.Println(p.Matrix)
}

func main() {
    initialMatrix := [4][4]int{}

    newPlay := Play{Matrix: initialMatrix}

    newPlay.Randomize()

    fmt.Println(newPlay.Matrix)
}

This is the result

# Randomize()
# fmt.Println(p.Matrix[1][3])
2

# Randomize()
# fmt.Println(p.Matrix)
[[0 0 0 0] [0 0 0 2] [0 0 0 0] [0 0 0 0]]

# main()
# fmt.Println(newPlay.Matrix)
[[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]]

It’s shown that inside the Randomize() method, it’s able to change the value. But the changes aren’t carried over into the main even if it already calls the Randomize(). Any idea why? Is it because of scoping problem?

Solution

The problem here is that you are using a non-pointer receiver for your Randomize method.

The quick fix:

func (p *Play) Randomize() {
    p.Matrix[1][3] = 2
    fmt.Println(p.Matrix[1][3])
    fmt.Println(p.Matrix)
}

the explanation:

"receivers" are just fancy parameters for functions. When you pass a parameter(or receiver) as a non-pointer, Go will create a copy of the parameter and operate over the copy. This means that non-pointer parameters and receivers cannot be modified internally; after all, inside the function you are operating over a copy, not the original value.

When using a pointer, you can now modify the original parameter(/receiver). This is what pointers are for, and they are usually implied in other languages like Java or Python. Here, you need to explicitly say "this function must act on the ORIGINAL caller"(pointer) rather than "this function must act on something equivalent to the caller"(non-pointer).

Answered By – Badashi

Answer Checked By – Willingham (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.