我有一个我正在使用的结构,我不确定如何正确地循环它。我想访问字段名称,但它所做的只是在每个循环中逐步计数。
这是我的结构:
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列名称。
答案 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)
}
}
}
答案 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")
}
}