Go: proposal: Go 2: syntax for declaring nested structs

Created on 12 Jun 2018  路  4Comments  路  Source: golang/go

One of the frustrating points for newcomers to Go is the syntax for declaring nested structs. Especially considering other languages make it concise and easily memorable.

Right now that syntax for declaring it in one go looks like this:

type B struct {
    Name        string `json:"name"`
    Description string `json:"description"`
    Tags        string `json:"tags"`
}
type A struct {
    B B `json:"b"`
}

// Syntax for declaring instances of A or B
b := B{
    Name: "somename",
}
a := &A{
    B: B{
        Name:        "somename",
        Description: "abc",
    },
}

And I've noticed a few times that intuitively, people tend to keep the struct A declaration nested, and try to guess the syntax for declaring one instance of it.
That syntax is the following, and it's pretty complicated (again I'm comparing to other scripting languages that provide no type safety at all, it's a pretty unfair comparison):

type A struct {
    B struct {
        Name        string `json:"name"`
        Description string `json:"description"`
        Tags        string `json:"tags"`
    } `json:"b"`
}

// Syntax for declaring an instance of A
// notice it's impossible to declare an instance of B, it not being a type by itself
a := &A{
    B: struct {
        Name        string `json:"name"`
        Description string `json:"description"`
        Tags        string `json:"tags"`
    }{
        Name:        "somename",
        Description: "abc",
    },
}

Which leads to my syntax proposal for doing the same thing:

// even while keeping the type declaration nested
type A struct {
    B struct {
        Name        string `json:"name"`
        Description string `json:"description"`
        Tags        string `json:"tags"`
    } `json:"b"`
}
// A.B would automatically be accessible as a type itself
b := A.B{
    Name: "somename",
}
// creating an A would be more concise without losing any clarity about types
a := &A{
    B: A.B{
        Name:        "somename",
        Description: "abc",
    },
}

What is your opinion about this syntax ?

I'm not familiar with the go codebase yet, but I'd be happy to start looking into it, I just wish to see how the go community would receive such a change first.

Also, are there strong reasons (that I don't see) to not introduce that change ?

FrozenDueToAge Go2 LanguageChange Proposal

Most helpful comment

https://github.com/golang/go/issues/21496 seems like a clearer way to address the same use-case.

All 4 comments

https://github.com/golang/go/issues/21496 seems like a clearer way to address the same use-case.

@bcmills that's a valid point, thanks for pointing to the other issue.

I'm not sure if the elision would always be clearer, but it's certainly more concise, and there's always the possibility of specifying types if any code gets unclear, so I'd be happy with the solution you pointed out !

I also like the idea of making sub-types accessible without breaking the nesting visually though.

I don't like this, mainly because now A.B becomes ambiguous. It's not intuitive to me to have A.B sometimes be a value, and sometimes be a type. This would also definitely complicate the Go spec since there is no other case when something like this occurs.

As @bcmills says, #21496 seems easier to understand, and as @deanveloper says, using the same name as both a type and a value has the potential to be quite confusing. We aren't going to make this change, but thanks for the suggestion.

Was this page helpful?
0 / 5 - 0 ratings