在Go语言中循环遍历结构体并访问数组的方法是:

huangapple go评论77阅读模式
英文:

looping over struct and accessing array in golang

问题

我的问题是:

  1. 我想能够循环遍历每个服务器,并在该循环内部循环遍历UsageData。
  2. 我当前的循环给我一个关于遍历资产的错误,不确定原因。
  3. 我无法访问assets.Server.UsageData。

以下是我的代码:https://go.dev/play/p/ttNVW5_Q4Ys

package main

import (
	"encoding/json"
	"fmt"
)

type Asset struct {
	Server struct {
		Host string `json:"host"`
		Port string `json:"port"`
	} `json:"server"`
	Postgres struct {
		Host      string `json:"host"`
		User      string `json:"user"`
		Password  string `json:"password"`
		DB        string `json:"db"`
		UsageData []struct {
			Region string `json:"Region"`
			Mbps   int    `json:"Mpbs"`
		} `json:"UsageData"`
	} `json:"database"`
}

func main() {
	jsonConfig := []byte(`[
	{
		"server":{
			"host":"serverA",
			"port":"8080"},
		"database":{
			"host":"serverA",
			"user":"db_user",
			"password":"supersecret",
			"db":"A_db",
			"UsageData":[{"Region":"US","Mbps":100}, {"Region":"EU","Mbps":140}]
		}
	},
	{
		"server":{
			"host":"serverB",
			"port":"8383"},
		"database":{
			"host":"serverB",
			"user":"db_user2",
			"password":"acbd123",
			"db":"B_db",
			"UsageData":[{"Region":"US","Mbps":58}, {"Region":"EU","Mbps":250}]
		}	
	}
]`)
	var assets []Asset
	err := json.Unmarshal(jsonConfig, &assets)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Assets: %+v\n", assets)

	for _, asset := range assets {
		fmt.Printf("%v\n", asset)
		for _, Usage := range asset.Postgres.UsageData {
			fmt.Printf("%v\n", Usage)
		}
	}
}

带有正确答案的代码,我错误地调用了嵌套结构

https://go.dev/play/p/tEbA405WWbC

英文:

My issue is

  1. I want to be able to loop over each server and within that loop, loop over UsageData
  2. My current loop gives me an error about ranging over assets not sure why
  3. I cant access assets.Server.UsageData

Here is my code : https://go.dev/play/p/ttNVW5_Q4Ys

package main
import (
"encoding/json"
"fmt"
)
type Asset struct {
Server struct {
Host string `json:"host"`
Port string `json:"port"`
} `json:"server"`
Postgres struct {
Host      string `json:"host"`
User      string `json:"user"`
Password  string `json:"password"`
DB        string `json:"db"`
UsageData []struct {
Region string `json:"Region"`
Mbps   int    `json:"Mpbs"`
} `json:"UsageData"`
} `json:"database"`
}
func main() {
jsonConfig := []byte(`[
{
"server":{
"host":"serverA",
"port":"8080"},
"database":{
"host":"serverA",
"user":"db_user",
"password":"supersecret",
"db":"A_db",
"UsageData":[{"Region":"US","Mbps":100}, {"Region":"EU","Mbps":140}]
}
},
{
"server":{
"host":"serverB",
"port":"8383"},
"database":{
"host":"serverB",
"user":"db_user2",
"password":"acbd123",
"db":"B_db",
"UsageData":[{"Region":"US","Mbps":58}, {"Region":"EU","Mbps":250}]
}	
}
]`)
var assets []Asset
err := json.Unmarshal(jsonConfig, &assets)
if err != nil {
panic(err)
}
fmt.Printf("Assets: %+v\n", assets)
//fmt.Printf("Config: %+v\n", assets.Server.Host)
//fmt.Printf("Config: %+v\n", assets.database.UsageData)
//fmt.Printf("Config: %+v\n", assets.Server.UsageData)
for _, asset := range assets {
fmt.Printf("%v\n", asset)
//for _, Usage := range assets.UsageData {
//	fmt.Printf("%v\n",Usage)
//}
}
}

** Code with the correct answer, I was calling the nested struct incorrectly**

https://go.dev/play/p/tEbA405WWbC

答案1

得分: 2

提供的jsonConfig在技术上并不是错误的,但是键应该是唯一的(参见问题)。看起来encoding/json会用最后一次出现的值覆盖之前的值。

所以你有两个选项:

  1. jsonConfig更改为[{asset1}, {asset2}](参见修复后的示例
  2. 实现自定义的解码器

我强烈推荐第一个选项。

英文:

Provided jsonConfig is not technically incorrect but keys SHOULD be unique (see question).
It seems that encoding/json will override value with last occurrence.

So you have 2 options:

  1. change jsonConfig to [{asset1}, {asset2}] (see fixed playground)
  2. implement custom unmarshaler

I definitely recommend first option.

huangapple
  • 本文由 发表于 2022年3月17日 15:45:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/71508641.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定