Type name for nested struct field?

Hi all,

Is there has any plan to supports this kind of struct syntax:

type A struct {
    B struct {
        Field1 int
        Field2 int
    } 
}

var a A

a.B = A.B{1, 2}

This syntax is useful to define communication protocol.

Hey @Mingda,

You can already use that kind of syntax by initializing B like so:

a.B = struct {
	Field1 int
	Field2 int
}{
	1, 2,
}

Or if you want, you could also initialize A completely with the following:

a := A{
	B: struct {
		Field1 int
		Field2 int
	}{
		1, 2,
	},
}

Edit: Just by the way, if you were actually referring to initializing B specifically with A.B{...} rather than typing out the full structure like above, then I think I jumped to my answer without properly understanding your question and for that I’m sorry :slight_smile:

Thanks @radovskyb,

I know the initializing syntax, but this is some kind of “repeat your self”.

Think about a communication protocol, 2 or 3 level nested field is common.

For example:

type ProtocolA struct {
    Items []struct{
        ID int
        Position struct {
            X int
            Y int
        }
    }
}

The nested types just used in this protocol, define them by another struct will make the code hard to read.

For example (imagine you have many protocols like this in your project):

type ProtocolA struct {
    Items []ProtocolA_Items
}

type ProtocolA_Items struct {
    ID     int
    Field2 ProtocolA_Items_Position
}

type ProtocolA_Items_Position struct {
    X int
    Y int
}

But if we use nested type, we need to repeat those struct definition at anywhere you initializing the protocol.

“Hard to read” and “Repeat” not good for software engining.

I might not be the best suited person to answer this question since I’m far from an expert at Go, but why not just use simple composition? Example:

package main

import "fmt"

type Protocol struct {
	Items []Item
}

type Item struct {
	ID int
	Position
}

type Position struct {
	X, Y int
}

func main() {
	items := []Item{
		{0, Position{X: 10, Y: 20}},
		{1, Position{X: 15, Y: 10}},
	}

	p := Protocol{Items: items}

	fmt.Println(p)
}

Edit: Well I suppose you are just basically doing that, but what I mean is pretty much, it’s quite simple to keep it really clean to set things up like in the main function above. Even with quite deeply nested structures it’s still very simple.

Actually here is a better example that’s much more nested than my previous answer, but to me, still looks very readable and easy to use and understand.

I agree that your first example is clean and concise, but for me your second example is hard to read mostly because of the Long_Unwieldy_Mid_Caps_Mixed_With_Underscores naming style. The convention in Go is to not use underscores in names at all. And short names are always better. The code in Benjamin’s reply already wins a lot in terms of readability by choosing short, concise names.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.