I’m using JSON to get some values into a variable from an external source.
I have a type like this that json.Unmarshal puts values into:
type Frame struct {
Type string
Value map[string]interface{}
}
var data Frame
After unmarshal, I can access a the type by: data.Type
but if I try doing something like:
if data.Type == "image" {
fmt.Printf("%s\n", data.Value.Imagedata)
}
The compiler complains about no such value data.Value.Imagedata.
So my question is, how do I reference properties in Go that I know will be there depending on some condition?
Doing this works:
type Image struct {
Filename string
}
type Frame struct {
Type string
Value map[string]interface{}
}
But that isn’t very flexible as I will be receiving different Values.
json.Unmarshalwill do its best to place the data where it best aligns with your type. Technically your first example will work, but you are trying to access theValuefield with dot notation, even though you declared it to be a map:This should give you some form of output:
… considering that “Imagedata” was a key in the JSON.
You have the option of defining the type as deeply as you want or expect the structure to be, or using an
interface{}and then doing type assertions on the values. With theValuefield being a map, you would always access the keys likeValue[key], and the value of that map entry is aninterface{}which you could type assert likeValue[key].(float64).As for doing more explicit structures, I have found that you could either break up the objects into their own types, or define it nested in one place:
Nested (with anonymous struct)
Seperate structs
I’m still learning Go myself, so this the extent of my current understanding :-).