3

I'm trying to understand nested structs in go, so I made a little test: (playground)

type A struct {
    a string
}

type B struct {
    A
    b string
}

func main() {
    b := B{A{"a val"}, "b val"}

    fmt.Printf("%T -> %v\n", b, b)   // B has a nested A and some values 
    // main.B -> {{a val} b val}

    fmt.Println("b.b ->", b.b)       // B's own value
    // b.b -> b val

    fmt.Println("b.A.a ->", b.A.a)   // B's nested value
    // b.a -> a val

    fmt.Println("b.a ->", b.a)       // B's nested value? or own value?
    // b.a -> a val
}

So how and why the last two lines work? Are they are same? Which should I use?

1 Answer 1

5

They are the same. See the Go Spec on selectors:

For a value x of type T or *T where T is not a pointer or interface type, x.f denotes the field or method at the shallowest depth in T where there is such an f. If there is not exactly one f with shallowest depth, the selector expression is illegal.

Note that this means that b.a is illegal if type B embeds two types with the same field on the same depth:

type A1 struct{ a string }
type A2 struct{ a string }
type B struct {
    A1
    A2
}

// ...
b := B{A1{"a1"}, A2{"a2"}}
fmt.Println(b.a) // Error: ambiguous selector b.a

Playground: http://play.golang.org/p/PTqm-HzBDr.

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

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.