简体   繁体   中英

Better way to type assert interface to map in Go

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)?

Its really 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)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM