I'm writing a test program in Go, which takes 5 inputs and will marshal it to JSON and then return it back to the caller.
The JSON structure is defined externally to me so I'm unable to simplify it - even though I reckon it needs it - so I just have to deal with the annoying structure of the payload.
Trouble is, I cannot get it to parse/initialise correctly at all. It keeps complaining about "expected expression" and I can't work out why.
It's worth noting that I had to use one of those JSON-to-struct generators as I couldn't work out what the struct should actually look like, then I tried to clean it up a bit. There could be an error here I'm not seeing.
json
{
"outer": [
{
"inner": {
"key1": "...",
"key2": "...",
"key3": "...",
"key4": "...",
"key5": "..."
}
}
]
}
structs
type Payload struct {
Outer []struct {
Inner InnerTestData `json:"inner"`
} `json:"outer"`
}
type InnerTestData struct {
Alertname string `json:"key1"`
QueueInHrs string `json:"key2"`
QueueOutHrs string `json:"key3"`
Urgency string `json:"key4"`
Impact string `json:"key5"`
}
code
func main() {
if len(os.Args) != 5 {
fmt.Println("ERROR: There should be 5 args")
os.Exit(1)
}
key1 := os.Args[1]
key2 := os.Args[2]
key3 := os.Args[3]
key4 := os.Args[4]
key5 := os.Args[5]
innerTestData := InnerTestData{
Key1: key1,
Key2: key2,
Key3: key3,
Key4: key4,
Key5: key5,
}
payload := Payload{
Outer: []struct{
Inner: innerTestData,
},
}
}
I'm just confused as to how I should actually be parsing this in to the Payload struct, I've tried every combination I can think of without any luck. I'm aware this is probably something simple going wrong, but the whole having to create a struct that perfectly matches the JSON payload situation is really over-complicated and confusing, I find.
Any help appreciated. Cheers.
CodePudding user response:
Use the following composite literal:
payload := Payload{
Outer: []struct {
Inner InnerTestData `json:"inner"`
}{
{Inner: innerTestData},
},
}
Note that the composite literal for the inner struct variable must be surrounded by {}.
A composite literal with an anonymous struct type is verbose. The type must be repeated in the literal. Simplify by replacing the anonymous type with a named type.
type Outer struct { // <-- new named type
Inner InnerTestData `json:"inner"`
}
type Payload struct {
Outer []Outer `json:"outer"` // <-- use it here
}
The composite literal with the named type is:
payload := Payload{
Outer: []Outer{
{Inner: innerTestData},
},
}
The compiler reports an error for Outer: []struct{ Inner: innerTestData, } because the compiler expects a struct definition following the struct keyword.
