在 Go 中键入断言接口以进行映射的更好方法

Better way to type assert interface to map in Go

我将 JSON 存储在一个包含嵌套对象的文件中。

结构如下所示:

{
  "users" : {
    "enxtropayy": {
      "pass": "",
      "root": true,
      "admin": true,
      "moderator": true
    }
  }
}

太棒了,我希望能够通过 Go 访问“enxtropayy”用户:

usr, _ := ioutil.ReadFile("userInfo.JSON")
var data map[string]interface{}
json.Unmarshal(usr,&data)
fmt.Println(data["users"])

它打印 map[enxtropayy:map[admin:true moderator:true pass: root:true]]

这很好,但我不能深入一层,我发现这是因为接口没有键。

所以我重新编写了我的 Go 代码,如下所示:

var data interface{}
json.Unmarshal(usr,&data)
fmt.Println(data.(interface{}).(map[string]interface{})["users"].(interface{}).(map[string]interface{})["enxtropayy"])

有效!但是,每次我想访问另一个嵌套层时,我都必须执行 .(map[string]interface{})["keyName"],这看起来不是很“整洁”,而且写起来有点乏味。这似乎也没有必要,而且可能不是最佳做法。整个“类型断言”和“interfaces/maps”对我来说是新的,所以我不太了解我在做什么,这是我想改进的地方。

有没有另一种方法我可以键入断言映射的接口(或者更好的方法将 JSON 完全存储在 Go 中),你能解释一下它是如何工作的吗(给一个人一条鱼一日之食,授人以渔,以食为生)?

最好只使用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)
}