I'm using json to get some values into a struct from an external source. Using UnMarshal to put the values in a struct.
I have a struct like this that UnMarshal puts values into:
type Frame struct{ Type string Value map[string]interface{} } var data Frame
After the UnMarshal, I can access type by: data.Type
but if I try doing something like:
if data.Type == 'image'{ fmt.Println(fmt.Sprintf("%s", data.Value.Imagedata)) }
The compiler complains about no such value data.Value.Imagedata
So my question is, how do I reference properties in GoLang in the code 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
The UnMarshal wil do its best to place the data where it best aligns with your struct. Technically your first example will work, but you are trying to access the Value field with dot notation, even though you declared it to be a map:
This should give you some form of output:
if data.Type == 'image'{ fmt.Printf("%v\n", data.Value["Imagedata"]) }
... considering that "Imagedata" was a key in the json.
You have the option of defining the struct as deeply as you want or expect the structure to be, or using an interface{} and then doing type assertions on the values. With the Value field being a map, you would always access the keys like Value[key], and then value of that map is an interface{} which you could type assert like Value[key].(float64)
As for doing more explicit structures, I have found that you could either break up the objects into their own structs, or, define it nested in one place:
Nested (with anonymous struct)
type Frame struct { Type string Value struct { Imagedata string `json:"image_data"` } }
Seperate structs
type Frame struct { Type string Value value } type value struct { Imagedata string `json:"image_data"` }
I'm still learning Go myself, so this the extent of my current understanding :-)