2

I have a nested struct. I want to update it inside a method. For some reason, the update doesn't take place.

    package main

    import "fmt"

    type B struct {
        c int
    }

    type A struct {
        b B
    }

    func (a A) updateB(n int) {
        a.b.c = n
    }

    func main() {
        a := A{b: B{c: 5}}

        fmt.Println(a)
        a.updateB(42)
        fmt.Println(a)
    }

The output I get is

{{5}}
{{5}}

In most languages, I'd expect it to be updated. Is this some special Go behavior? How does one go about updating nested structs in Go?

4 Answers 4

6

It is because you are using a value receiver so the updateB method receives a copy of the value of A rather than a pointer to the memory that contains the a variable. Using a pointer receiver fixes the problem:

package main

import "fmt"

type B struct {
    c int
}

type A struct {
    b B
}

func (a *A) updateB(n int) {
    a.b.c = n
}

func main() {
    a := A{b: B{c: 5}}

    fmt.Println(a)
    a.updateB(42)
    fmt.Println(a)
}

https://play.golang.org/p/XBrxd246qT3

See also:

Value receiver vs. Pointer receiver in Golang?

Sign up to request clarification or add additional context in comments.

Comments

3

It's not because the struct is nested, rather it's because you need a pointer receiver to modify the value to which the receiver points, in this case your a variable.

Without the pointer your UpdateB method would only be updating a copy of the original A struct value.

See the following:

package main

import "fmt"

type B struct {
    c int
}

type A struct {
    b B
}

func (a *A) UpdateB(n int) {
    a.b.c = n
}

func main() {
    a := A{b: B{c: 5}}

    fmt.Println(a)
    a.UpdateB(50)
    fmt.Println(a)
}

Comments

3

The problem is with your update function. You are supposed to add it to the pointer to A.

func (a *A) updateB(n int) {
    a.b.c = n
}

Comments

1

For any interface for its objects to be updated by a function you need to pass the object by reference.

package main

import "fmt"

type B struct {
    c int
}

type A struct {
    b B
}

func (a *A) updateB(n int) {
    a.b.c = n
}

func main() {
    a := A{b: B{c: 5}}

    fmt.Println(a)
    a.updateB(42)
    fmt.Println(a)
}

https://play.golang.org/p/_o5sRApo6WP

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.