Quick and Dirty Object Access in Go
Assumed audience: Developers/technical people who use Go as a programming language
This probably isn't too difficult to write but it's recursive and I had fun putting it together so here it is
Basically, I was trying to access a deeply nested object that was parsed from BurntSushi/toml in some generic fashion and it was getting annoying to constantly cast things and do the necessary checks at every level so I made two utilities that can access nested data a bit more conveniently
First off, here's a helper type to sprinkle around:
type dynamic = map[string]any
Then, here's the version that will panic if it hits something it's not expecting:
func unsafeIndex(data dynamic, path ...string) any {
if len(path) == 0 {
return data
}
inner := data[path[0]]
if len(path) == 1 {
return inner
}
return unsafeIndex(inner.(dynamic), path[1:]...)
}
And the version that returns the appropriate errors along the way:
func safeIndex(data dynamic, path ...string) (any, error) {
if len(path) == 0 {
return data, nil
}
inner, ok := data[path[0]]
if !ok {
return data, fmt.Errorf("Error indexing path %v for %v", path, data)
}
if len(path) == 1 {
return inner, nil
}
dyn, ok := inner.(dynamic)
if !ok {
return dyn, fmt.Errorf("Error indexing into inner struct %v for %v", path, inner)
}
return safeIndex(dyn, path[1:]...)
}
Using them is also fairly normal, as seen below:
// whatever you're doing to decode the data. e.g. JSON/TOML parser
var output dynamic
decodeData(FILE_CONTENT, &output)
dynamicSources, err := safeIndex(output, "some", "deeply", "nested", "property")
if err != nil {
panic(err)
}