我正在尝试使用golang中的JSON.Marshal()从地图创建JSON字符串。但是,int值显示为由双引号括起来的字符串。
我的代码正在输出:
{ "age":
{
"$gt":"22",
"$lt":"20"
},
"location":
{
"$eq":"london"
},
"name":{
"$eq":"fred"
}
}
而不是
{ "age":
{
"$gt":22,
"$lt":20
},
"location":
{
"$eq":"london"
},
"name":{
"$eq":"fred"
}
}
我正在使用:
var output_map = map[string]map[string]string{}
//Populate map here
output_json, err := json.Marshal(output_map)
if err!= nil {
fmt.Println("Error encoding JSON")
}
fmt.Println(output_json)
我的理解是,如果提供了JSON.Marshal()将正确打印整数,但我的地图将不包含整数。我可以将我的地图更改为map [string] map [string] int {}但是它不会包含'name'和'location'的字符串值。
最终的问题是我需要map包含int和string值。某种map [string] map [string] {}。
我怎样才能做到这一点?提前谢谢。
哈利
答案 0 :(得分:3)
如果您无法使用正确类型的结构描述数据,请考虑使用值为interface{}
的值的地图(基本上是任何类型):
output_map := map[string]map[string]interface{}{}
例如:
output_map := map[string]map[string]interface{}{
"age": {
"$gt": 18,
},
"location": {
"eq": "London",
},
}
bytes, err := json.MarshalIndent(&output_map, "", " ")
if err != nil {
panic(err)
}
// {
// "age": {
// "$gt": 18
// },
// "location": {
// "eq": "London"
// }
// }
当然,使用interface{}
类型不是最佳做法;然而,它有时是完成某些事情的唯一方法。
答案 1 :(得分:1)
我同意maerics,
如果你必须避免使用结构,那么 map[string]interface{}
就可以了。
根据您的内容,我假设您正在处理mongodb查询 所以可能以下代码有帮助。
如果您要从中查询mongodb,我会推荐使用mgo-driver mgo.v2 。
它实现了一个自定义类型 bson.M ,它与上面提到的相同,但也适用于查询数据库。
除此之外,它使代码更具可读性。
<强>示例:强>
package main
import (
"fmt"
"gopkg.in/mgo.v2/bson"
"encoding/json"
)
func main() {
bsonMap := bson.M{
"age": bson.M{
"$gt": 22,
"$lt": 20,
},
"location": bson.M{"$eq": "london",},
"name": bson.M{"$eq": "fred"},
}
bytes, err := json.Marshal(bsonMap)
if err != nil {
panic(err)
}
fmt.Println(string(bytes))
}
答案 2 :(得分:1)
我们可以声明整数和字符串混合映射的变量,如下所示。
var variable_name = map[string]interface{}{}
例如
var variable_name = map[string]interface{}{
"name": c.String("name"),
"age": c.Int("age"),
}
答案 3 :(得分:0)
您的代码按预期工作:map[string]map[string]string{}
仅包含字符串值,因此json.Marshal(interface{})
返回json string
并带有编组的string
值。
我认为您应该使用struct
代替map
。只需创建一个结构,如下所示:
type Age struct {
Gt int `json:"gt"`
Lt int `json:"lt"`
}
type Person struct {
Age Age `json:"age"`
Location string `json:"location"`
Name string `json:"name"`
}
并使用标准json.Marshal(interface{})
方法对其进行封送。
(在此代码中不需要json
标记,但如果要更改序列化json字符串中的字段名称,则可以使用它。
我使用test.go
中的以下代码创建main()
文件:
person := Person{
Age{
22,
20,
},
"London",
"Fred",
}
serialized, e := json.Marshal(person)
if e != nil {
fmt.Println(e)
return
}
fmt.Println(string(serialized))
然后返回:
{
"age":
{
"gt":22,
"lt":20
},
"location":"London",
"name":"Fred"
}
PS 我建议您不要使用map[string]map[string]interface{}
,因为在这种情况下,您需要自定义Unmarshaller
(以填充map
) 。使用结构,您可以通过这种方式解组它:
deserialized := Person{}
e = json.Unmarshal(serialized, &deserialized)
if e != nil {
fmt.Println("can't deserialize:", e)
return
}