I am storing JSON in a file in which it has nested objects.
The structure looks like this:
{
"users" : {
"enxtropayy": {
"pass": "",
"root": true,
"admin": true,
"moderator": true
}
}
}
Soooo, I want to be able to access the "enxtropayy" user via Go:
usr, _ := ioutil.ReadFile("userInfo.JSON")
var data map[string]interface{}
json.Unmarshal(usr,&data)
fmt.Println(data["users"])
It prints map[enxtropayy:map[admin:true moderator:true pass: root:true]]
This is great and all, but I can't go deeper than one layer, and I found out that it's because interfaces don't have keys.
So instead I re-wrote my Go code to look like this:
var data interface{}
json.Unmarshal(usr,&data)
fmt.Println(data.(interface{}).(map[string]interface{})["users"].(interface{}).(map[string]interface{})["enxtropayy"])
It works! But, I have to do .(map[string]interface{})["keyName"]
every time I want to access another nested layer and that doesn't seem very "neat" and is a bit tedious to write. It also seems unnecessary and is probably not the best practice. The whole "type assertion" and "interfaces/maps" is new to me so I don't know much about what I'm doing, which is something I want to improve on.
Is there another way I can type assert an interface to a map (or a better way to store the JSON in Go altogether), and could you also explain how it works (give a man a fish and he will eat for a day; teach a man to fish and he will eat for a living)?
It's better to just use struct
when possible:
package main
import (
"encoding/json"
"fmt"
)
const s = `
{
"users" : {
"enxtropayy": {
"admin": true, "moderator": true, "root": true,
"pass": ""
}
}
}
`
func main() {
var t struct {
Users map[string]struct {
Admin, Moderator, Root bool
Pass string
}
}
json.Unmarshal([]byte(s), &t)
// {Users:map[enxtropayy:{Admin:true Moderator:true Root:true Pass:}]}
fmt.Printf("%+v\n", t)
}