gpt4 book ai didi

json - 在 Go 中将 YAML 转换为 JSON

转载 作者:IT王子 更新时间:2023-10-29 02:01:57 30 4
gpt4 key购买 nike

我有一个 YAML 格式的配置文件,我试图通过 http API 调用将其输出为 JSON。我正在使用 gopkg.in/yaml.v2 解码。 Yaml 可以有非字符串键,这意味着 yaml 被解码为 map[interface{}]interface{},这是 Go 的 JSON 编码器不支持的。因此我在解码之前转换为 map[string]interface{} 。但我仍然得到:json: unsupported type: map[interface {}]interface"{}。我不明白。变量 cfy 不是 map [接口(interface){}]接口(interface){}

import (
"io/ioutil"
"net/http"
"encoding/json"
"gopkg.in/yaml.v2"
)

func GetConfig(w http.ResponseWriter, r *http.Request) {
cfy := make(map[interface{}]interface{})
f, err := ioutil.ReadFile("config/config.yml")
if err != nil {
// error handling
}
if err := yaml.Unmarshal(f, &cfy); err != nil {
// error handling
}
//convert to a type that json.Marshall can digest
cfj := make(map[string]interface{})
for key, value := range cfy {
switch key := key.(type) {
case string:
cfj[key] = value
}
}
j, err := json.Marshal(cfj)
if err != nil {
// errr handling. We get: "json: unsupported type: map[interface {}]interface" {}
}
w.Header().Set("content-type", "application/json")
w.Write(j)
}

最佳答案

您的解决方案仅转换“顶级”级别的值。如果一个值也是一个映射(嵌套映射),您的解决方案不会转换它们。

此外,您仅使用 string 键“复制”值,其余部分将被排除在结果映射之外。

这是一个递归转换嵌套映射的函数:

func convert(m map[interface{}]interface{}) map[string]interface{} {
res := map[string]interface{}{}
for k, v := range m {
switch v2 := v.(type) {
case map[interface{}]interface{}:
res[fmt.Sprint(k)] = convert(v2)
default:
res[fmt.Sprint(k)] = v
}
}
return res
}

测试它:

m := map[interface{}]interface{}{
1: "one",
"two": 2,
"three": map[interface{}]interface{}{
"3.1": 3.1,
},
}
m2 := convert(m)
data, err := json.Marshal(m2)
if err != nil {
panic(err)
}
fmt.Println(string(data))

输出(在 Go Playground 上尝试):

{"1":"one","three":{"3.1":3.1},"two":2}

一些注意事项:

  • 为了隐藏 interface{} 键,我使用了 fmt.Sprint() 来处理所有类型。 switch 可以为已经是 string 值的键提供专用的 string 大小写,以避免调用 fmt.Sprint()。这完全是出于性能原因,结果是一样的。

  • 上面的convert() 函数没有进入 slice 。因此,例如,如果 map 包含一个值,该值是一个 slice ([]interface{}),它也可能包含 map ,则不会转换这些值。如需完整解决方案,请参阅下面的库。

  • 有一个库 github.com/icza/dyno它对此有优化的内置支持(披露:我是作者)。使用 dyno,这就是它的样子:

    var m map[interface{}]interface{} = ...

    m2 := dyno.ConvertMapI2MapS(m)

    dyno.ConvertMapI2MapS()也进入并转换 []interface{} slice 中的 map 。

另请参阅可能的重复项:Convert yaml to json without struct

关于json - 在 Go 中将 YAML 转换为 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50405874/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com