将嵌套的映射转换为JSON。

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

Marshaling a nested map into JSON

问题

我正在尝试将这个嵌套的map转换为JSON字符串。

map[
  description:Foo Bar
  url:http://foobar.co.uk
  theme_color:#1b1b1b
  markdown:kramdown
  sass:map[
    style:compressed
  ]
  collections:map[
    projects:map[
      output:true
      permalink:/project/:path
    ]
    jobs:map[
      output:true
      permalink:/job/:path
    ]
  ]
  title:Foo Bar
  email:foo@foobarco.uk
]

(从 fmt.Printf("%v", m) 清理后的输出)

最初会读取和解析一个配置文件,生成这个map,所以我事先不知道字段,这意味着我不能(?)使用结构体。

从YAML解组成这个 map[string]interface{} 的过程很顺利,但是当我将这个map传递给 json.Marshal 时,我会得到以下错误。

json: unsupported type: map[interface {}]interface{}

从阅读相关资料,我可以看到这个错误是因为JSON只支持字符串键。让我困惑的是,上面的map似乎没有任何非字符串键。

如果我移除嵌套的 sasscollections 键,它就可以正常转换了。

有没有可能对这个map进行一些健全性检查,确认所有的键实际上都是 string 而不仅仅是看起来像字符串的 interface{}

英文:

I'm trying to marshal this nested map into a JSON string.

map[
  description:Foo Bar
  url:http://foobar.co.uk
  theme_color:#1b1b1b
  markdown:kramdown
  sass:map[
    style:compressed
  ]
  collections:map[
    projects:map[
      output:true
      permalink:/project/:path
    ]
    jobs:map[
      output:true
      permalink:/job/:path
    ]
  ]
  title:Foo Bar
  email:foo@foobarco.uk
]

(Cleaned up output from fmt.Printf("%v", m))

Initially a config file is read and parsed to produce the map, so I don't know the fields in advance, meaning I can't(?) use a struct.

Unmarshalling from YAML into this map of map[string]interface{} works fine, but when I pass this map to json.Marshal, I get the following error.

json: unsupported type: map[interface {}]interface{}

From reading around, I can see that this error is thrown because JSON only supports string keys. What's confusing me, is that the map above doesn't seem to have any non-string keys.

If I remove the nested sass and collections keys, it marshals without any issues.

Is it possible to do some sanity check on the map to confirm that all the keys are infact string and not just interface{} looking like strings?

答案1

得分: 2

使用github.com/json-iterator/go包代替encode.json。它可以将map[interface{}]interface{}编码为JSON

https://github.com/json-iterator/go

英文:

Use github.com/json-iterator/go package instead of encode.json. It can encode map[interface{}]interface{} to JSON.

https://github.com/json-iterator/go

答案2

得分: 1

很可能,子映射是由YAML解析器创建为map[interface{}]interface{}。

使用"%#v"而不是"%v"打印出你的映射,你将看到类型。

以下是一个示例:

package main

import "fmt"

func main() {
    a := map[string]interface{}{
        "A": map[interface{}]interface{}{
            "B": 123,
        },
    }
    fmt.Printf("%#v\n", a)
}

输出结果为:

map[string]interface {}{"A":map[interface {}]interface {}{"B":123}}

这里是示例链接

英文:

Most likely, the sub-maps are being created as map[interface{}]interface{} by the YAML parser.

Print out your map with "%#v" instead of "%v" and you will see the types.

Here's an example

package main

import "fmt"

func main() {
	a := map[string]interface{}{
		"A": map[interface{}]interface{}{
			"B": 123,
		},
	}
	fmt.Printf("%#v\n",a)
}

Produces:

map[string]interface {}{"A":map[interface {}]interface {}{"B":123}}

答案3

得分: 0

你可以使用或从这个包中获取灵感:

https://github.com/ghodss/yaml

英文:

Also, you can use or get inspired by this package:

https://github.com/ghodss/yaml

huangapple
  • 本文由 发表于 2016年2月13日 15:53:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/35377477.html
匿名

发表评论

匿名网友

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

确定