【问题标题】:How to create a list of the dictionaries in Golang?如何在 Golang 中创建字典列表?
【发布时间】:2019-05-19 15:46:33
【问题描述】:

我是 Golang 的新手。

我将创建一个可调整大小的字典列表(这不是静态的),并将一些dict 附加到list。然后我想把它写在一个文件上,但是我很困惑。

我想要这样的东西:

[
 {"port": 161, "timeout": 1, "sleep_time": 5, "metrics": [
  {"tag_name": "output_current", "id": 3},
  {"tag_name": "input_voltage", "id": 2}
 ]},
 {"port": 161, "timeout": 1, "sleep_time": 4, "metrics": [
   {"tag_name": "destructor", "id": 10}
 ]}
]

[更新]:

Go 语言中的.append() Python 等价物是什么,比如下面的代码 sn-p?

list_ = []
dict_ = {"key": val}
list_.append(dict_)

我通过借用 this answer 找到了本节的答案([更新]):

type Dictionary map[string]interface{}
data := []Dictionary{}
dict1 := Dictionary{"key": 1}
dict2 := Dictionary{"key": 2}
data = append(data, dict1, dict2)

【问题讨论】:

  • 你看过切片和地图吗?
  • 是的,我做到了。那么 Golang 中不存在 list 和 dict 吗? Go 中的等价物是什么?
  • 这是我的切片,这是我的地图。这是给列表的,这是给字典的。(抱歉没办法)。无论如何,“字典列表”在 Go 中转换为“地图切片”(我也会考虑结构)。
  • 请浏览tour of Go covers append 部分。
  • 是的,有可能。在jsonioutil 的帮助下。

标签: json list dictionary go


【解决方案1】:

如果您需要将数据存储在基于字典/键值格式的切片中,那么使用切片和map[string]interface{}的组合就足够了。

在下面的示例中,我创建了一个名为 Dictionary 的新类型,以避免在复合文字上编写过多的 map[string]interface{} 语法。

type Dictionary map[string]interface{}

data := []Dictionary{
    {
        "metrics": []Dictionary{
            { "tag_name": "output_current", "id": 3 },
            { "tag_name": "input_voltage", "id": 2 },
        },
        "port":       161,
        "timeout":    1,
        "sleep_time": 5,
    },
    {
        "metrics": []Dictionary{
            { "tag_name": "destructor", "id": 10 },
        },
        "port":       161,
        "timeout":    1,
        "sleep_time": 4,
    },
}

但是,如果您的数据结构是固定的,那么我建议使用结构来代替map。下面是上面的另一个示例,使用相同的数据集但利用结构而不是map

type Metric struct {
    TagName string `json:"tag_name"`
    ID      int    `json:"id"`
}

type Data struct {
    Port      int      `json:"port"`
    Timeout   int      `json:"timeout"`
    SleepTime int      `json:"sleep_time"`
    Metrics   []Metric `json:"metrics"`
}

data := []Data{
    Data{
        Port:      161,
        Timeout:   1,
        SleepTime: 5,
        Metrics: []Metric{
            Metric{TagName: "output_current", ID: 3},
            Metric{TagName: "input_voltage", ID: 2},
        },
    },
    Data{
        Port:      161,
        Timeout:   1,
        SleepTime: 4,
        Metrics: []Metric{
            Metric{TagName: "destructor", ID: 10},
        },
    },
}

更新 1

为了能够将data 写入JSON 文件,特定的data 需要先转换为JSON 字符串。使用json.Marshal()map 数据(或结构对象数据)转换为JSON 字符串格式([]byte 类型)。

buf, err := json.Marshal(data)
if err !=nil {
    panic(err)
}

err = ioutil.WriteFile("fileame.json", buf, 0644)
if err !=nil {
    panic(err)
}

然后使用ioutil.WriteFile()将其写入文件。


如果您需要将 JSON 数据打印为字符串,则将 buf 转换为 string 类型。

jsonString := string(buf)
fmt.Println(jsonString)

上面的语句将产生下面的输出:

[{"port":161,"timeout":1,"sleep_time":5,"metrics":[{"tag_name":"output_current","id":"3"},{"tag_name":"input_voltage","id":"2"}]},{"port":161,"timeout":1,"sleep_time":4,"metrics":[{"tag_name":"destructor","id":"10"}]}]

【讨论】:

  • 感谢 +1 的回复,这很有道理。
  • 最后,我如何将这片地图(字典列表)存储在文件中?我用这个试过:ioutil.WriteFile("config.json", data, 0644) 但我得到了这个错误:'cannot use data (type []Dictionary) as type []byte in argument to ioutil.WriteFile' 我怎样才能把它写成 s json 文件?
  • @BenyaminJafari 请查看更新后的答案
  • 我将接受这一点,并编辑一些多余的Dictionary-我希望你不介意。
  • @BenyaminJafari np,很高兴它有帮助:-)
【解决方案2】:

所以你正在寻找的类型是:

dict => map
list => slice

一个简单的地图示例如下:

m:=map[string]int{
  "a": 1,
  "b": 2,
}

切片的一个简单示例如下所示:

var s []int
s = append(s, 1)
s = append(s, 2, 3)

所以为了你的类型把它放在一起:

[]map[string]interface{}{
    {
        "port":       161,
        "timeout":    1,
        "sleep_time": 5,
        "metrics": []map[string]interface{}{
            {"tag_name": "output_current", "id": "3"},
            {"tag_name": "input_voltage", "id": "2"},
        },
    },
    {
        "port":       161,
        "timeout":    1,
        "sleep_time": 4,
        "metrics": []map[string]interface{}{
            {"tag_name": "destructor", "id": "10"},
        },
    },
}

【讨论】:

  • 感谢您的回复。但我收到了这个错误:cannot use map[string]int literal (type map[string]int) as type map[string][]string in assignment 在你的简单例子中是map
  • map[string]int 更改为 map[string][]string
  • interface 是什么意思?这是否意味着任何类型?
  • 一个空接口可以(例如,interface{})。看看tour.golang.org/methods/14
猜你喜欢
  • 2021-12-06
  • 2011-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多