The error is accurate: Foo
is undefined. There is no type Foo
that your use of Foo
in a literal here can be referring to. You have a field Foo
, but its type is the anonymous type struct { Thing string }
. So, to fill that field with a literal, you would have to use its correct type name, which is not Foo
, it is struct { Thing string }
:
var testJSON = TestStruct{
Foo: struct {
Thing string
}{
Thing: "test thing string",
},
}
Most developers don't like to be this verbose with types they actually need to refer to, so they'll use named types for this case:
type TestStruct struct {
Foo Foo `json:Foo`
}
type Foo struct {
Thing string `json:Thing`
}
In which case your existing creation code would work fine. Anonymous types are most commonly used in cases where they don't need to be referred to, i.e. where reflection is the only way the types will be instantiated. This is the case when you want to unmarshal some JSON into a type, but you never want to create an instance of the type programatically. You'll even see cases where the outermost type isn't named, like:
type TestStruct struct {
Foo struct {
Thing string `json:Thing`
} `json:Foo`
}
var testJSON = struct {
Foo struct {
Thing string `json:Thing`
} `json:Foo`
}{}
json.Unmarshal(something, &testJSON)
fmt.Printf(testJSON.Foo.Thing)
This can be useful when you want to unmarshal a complex JSON document just to grab some deeply nested field(s).