在Go中使用嵌套的[]结构循环?

时间:2015-09-15 21:48:46

标签: json struct go

我有一个我正在使用的结构,我不确定如何正确地循环它。我想访问字段名称,但它所做的只是在每个循环中逐步计数。

这是我的结构:

type ImgurJson struct {
      Status int16 `json:"status"`
      Success bool `json:"success"`
      Data []struct {
            Width int16 `json:"width"`
            Points int32 `json:"points"`
            CommentCount int32 `json:"comment_count"`
            TopicId int32 `json:"topic_id"`
            AccountId int32 `json:"account_id"`
            Ups int32 `json:"ups"`
            Downs int32 `json:"downs"`
            Bandwidth int64 `json:"bandwidth"`
            Datetime int64 `json:"datetime"`
            Score int64 `json:"score"`
            Account_Url string `json:"account_url"`
            Topic string `json:"topic"`
            Link string `json:"link"`
            Id string `json:"id"`
            Description string`json:"description"`
            CommentPreview string `json:"comment_preview"`
            Vote string `json:"vote"`
            Title string `json:"title"`
            Section string `json:"section"`
            Favorite bool `json:"favorite"`
            Is_Album bool `json:"is_album"`
            Nsfw bool `json:"nsfw"`
             } `json:"data"`
}

这是我的功能:

func parseJson(file string) {
      jsonFile, err := ioutil.ReadFile(file)
      if err != nil {
            ...
            }
      jsonParser := ImgurJson{}
      err = json.Unmarshal(jsonFile, &jsonParser)
      for field, value := range jsonParser.Data {
            fmt.Print("key: ", field, "\n")
            fmt.Print("value: ", value, "\n")
      }
}

如何在Go中循环嵌套的[]结构并返回字段?我看过几篇关于反思的帖子,但我不明白这是否有助于我。我可以返回每个字段的值,但我不明白如何将字段名称映射到键值。

编辑:

将“密钥”重命名为“字段”,抱歉!没有意识到他们被称为领域。

我希望能够打印:

field: Width
value: 1234

我想学习如何执行此操作,以便稍后可以按名称调用特定字段,以便将其映射到SQL列名称。

3 个答案:

答案 0 :(得分:5)

此代码基于此示例,应该为您完成; http://blog.golang.org/laws-of-reflection

import "reflect"


for _, value := range jsonParser.Data {
            s := reflect.ValueOf(&value).Elem()
            typeOfT := s.Type()
            for i := 0; i < s.NumField(); i++ {
            f := s.Field(i)
            fmt.Print("key: ", typeOfT.Field(i).Name, "\n")
            fmt.Print("value: ", f.Interface(), "\n")
       }

}

请注意,在原始代码中,循环正在迭代名为Data的切片中的项目。每个东西都是匿名结构类型的对象。您不是在那时处理字段,从那里,您可以利用reflect包来打印结构中字段的名称和值。你不能仅仅range结构本身,操作没有定义。

答案 1 :(得分:0)

这是我们在评论中讨论的另一种方法:

请记住,虽然这比反射更快,但直接使用struct字段并使其成为指针(Data []*struct{....})仍然更好,更有效。

type ImgurJson struct {
    Status  int16                    `json:"status"`
    Success bool                     `json:"success"`
    Data    []map[string]interface{} `json:"data"`
}
//.....
for i, d := range ij.Data {
    fmt.Println(i, ":")
    for k, v := range d {
        fmt.Printf("\t%s: ", k)
        switch v := v.(type) {
        case float64:
            fmt.Printf("%v (number)\n", v)
        case string:
            fmt.Printf("%v (str)\n", v)
        case bool:
            fmt.Printf("%v (bool)\n", v)
        default:
            fmt.Printf("%v (%T)\n", v, v)
        }
    }
}

playground

答案 2 :(得分:0)

您还可以在嵌套结构上使用普通的golang for循环进行迭代。

type ImgurJson struct {
      Status int16 `json:"status"`
      Success bool `json:"success"`
      Data []struct {
            Width int16 `json:"width"`
            Points int32 `json:"points"`
            CommentCount int32 `json:"comment_count"`
            TopicId int32 `json:"topic_id"`
            AccountId int32 `json:"account_id"`
            Ups int32 `json:"ups"`
            Downs int32 `json:"downs"`
            Bandwidth int64 `json:"bandwidth"`
            Datetime int64 `json:"datetime"`
            Score int64 `json:"score"`
            Account_Url string `json:"account_url"`
            Topic string `json:"topic"`
            Link string `json:"link"`
            Id string `json:"id"`
            Description string`json:"description"`
            CommentPreview string `json:"comment_preview"`
            Vote string `json:"vote"`
            Title string `json:"title"`
            Section string `json:"section"`
            Favorite bool `json:"favorite"`
            Is_Album bool `json:"is_album"`
            Nsfw bool `json:"nsfw"`
             } `json:"data"`
}

func parseJson(file string) {
      jsonFile, err := ioutil.ReadFile(file)
      if err != nil {
            ...
            }
      jsonParser := ImgurJson{}
      err = json.Unmarshal(jsonFile, &jsonParser)
      for i :=0; i<len(jsonParser.Data); i++ {
            fmt.Print("key: ", jsonParser.Data[i].TopicId, "\n")
      }
}