简体   繁体   English

在 Go 中将断言接口键入到 map 的更好方法

[英]Better way to type assert interface to map in Go

I am storing JSON in a file in which it has nested objects.我将 JSON 存储在一个包含嵌套对象的文件中。

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: Soooo,我希望能够通过 Go 访问“enxtropayy”用户:

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]]它打印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.这很好,但我不能 go 比一层更深,我发现这是因为接口没有键。

So instead I re-wrote my Go code to look like this:因此,我改写了我的 Go 代码,如下所示:

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.它有效,但是,每次我想访问另一个.(map[string]interface{})["keyName"]层时,我都必须这样做. 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)?是否有另一种方法可以键入断言到 map 的接口(或者将 JSON 存储在 Go 中的更好方法;教一共)一个人钓鱼,他会以吃饭为生)?

Its really better to just use struct when possible:尽可能只使用struct真的更好:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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