将 Go 地图转换为 json

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24652775/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:24:27  来源:igfitidea点击:

Convert Go map to json

jsongo

提问by Cronos87

I tried to convert my Go map to a json string with encoding/jsonMarshal, but it resulted in a empty string.

我尝试使用encoding/jsonMarshal将 Go 地图转换为 json 字符串,但结果为空字符串。

Here's my code :

这是我的代码:

package main

import (
    "encoding/json"
    "fmt"
)

type Foo struct {
    Number int    `json:"number"`
    Title  string `json:"title"`
}

func main() {
    datas := make(map[int]Foo)

    for i := 0; i < 10; i++ {
        datas[i] = Foo{Number: 1, Title: "test"}
    }

    jsonString, _ := json.Marshal(datas)

    fmt.Println(datas)
    fmt.Println(jsonString)
}

My output is :

我的输出是:

map[9:{1 test} 2:{1 test} 7:{1 test} 3:{1 test} 4:{1 test} 5:{1 test} 6:{1 test} 8:{1 test} 0:{1 test} 1:{1 test}]

[]

I really don't know where I'm wrong. Thank you for your help.

我真的不知道我错在哪里。感谢您的帮助。

回答by julienc

If you had caught the error, you would have seen this:

如果你发现了错误,你会看到这个:

jsonString, err := json.Marshal(datas)
fmt.Println(err)

// [] json: unsupported type: map[int]main.Foo

The thing is you cannot use integers as keys in JSON; it is forbidden. Instead, you can convert these values to strings beforehand, for instance using strconv.Itoa.

问题是你不能在 JSON 中使用整数作为键;这是被禁止的。相反,您可以预先将这些值转换为字符串,例如使用strconv.Itoa.

See this post for more details: https://stackoverflow.com/a/24284721/2679935

有关更多详细信息,请参阅此帖子:https: //stackoverflow.com/a/24284721/2679935

回答by OneOfOne

It actually tells you what's wrong, but you ignored it because you didn't check the error returned from json.Marshal.

它实际上告诉您出了什么问题,但是您忽略了它,因为您没有检查从json.Marshal.

json: unsupported type: map[int]main.Foo

json: unsupported type: map[int]main.Foo

JSON spec doesn't support anything except strings for object keys, while javascript won't be fussy about it, it's still illegal.

JSON 规范不支持除对象键字符串之外的任何内容,而 javascript 不会对此大惊小怪,但它仍然是非法的。

You have two options:

您有两个选择:

1 Use map[string]Fooand convert the index to string (using fmt.Sprint for example):

1 使用map[string]Foo索引并将其转换为字符串(例如使用 fmt.Sprint):

datas := make(map[string]Foo, N)

for i := 0; i < 10; i++ {
    datas[fmt.Sprint(i)] = Foo{Number: 1, Title: "test"}
}
j, err := json.Marshal(datas)
fmt.Println(string(j), err)

2 Simply just use a slice (javascript array):

2 只需使用一个切片(javascript 数组):

datas2 := make([]Foo, N)
for i := 0; i < 10; i++ {
    datas2[i] = Foo{Number: 1, Title: "test"}
}
j, err = json.Marshal(datas2)
fmt.Println(string(j), err)

playground

playground

回答by vim

Since this question was asked/last answered, support for non string key types for maps for json Marshal/UnMarshal has been added through the use of TextMarshalerand TextUnmarshalerinterfaces here. You could just implement these interfaces for your key types and then json.Marshalwould work as expected.

由于这个问题被问到/最后回答了,通过使用TextMarshalerTextUnmarshaler接口在这里添加了对 json Marshal/UnMarshal 映射的非字符串键类型的支持。您可以为您的密钥类型实现这些接口,然后json.Marshal按预期工作。

package main

import (
    "encoding/json"
    "fmt"
    "strconv"
)

// Num wraps the int value so that we can implement the TextMarshaler and TextUnmarshaler 
type Num int

func (n *Num) UnmarshalText(text []byte) error {
    i, err := strconv.Atoi(string(text))
    if err != nil {
        return err
    }
    *n = Num(i)
    return nil
}

func (n Num) MarshalText() (text []byte, err error) {
    return []byte(strconv.Itoa(int(n))), nil
}

type Foo struct {
    Number Num    `json:"number"`
    Title  string `json:"title"`
}

func main() {
    datas := make(map[Num]Foo)

    for i := 0; i < 10; i++ {
        datas[Num(i)] = Foo{Number: 1, Title: "test"}
    }

    jsonString, err := json.Marshal(datas)
    if err != nil {
        panic(err)
    }

    fmt.Println(datas)
    fmt.Println(jsonString)

    m := make(map[Num]Foo)
    err = json.Unmarshal(jsonString, &m)
    if err != nil {
        panic(err)
    }

    fmt.Println(m)
}

Output:

输出:

map[1:{1 test} 2:{1 test} 4:{1 test} 7:{1 test} 8:{1 test} 9:{1 test} 0:{1 test} 3:{1 test} 5:{1 test} 6:{1 test}]
[123 34 48 34 58 123 34 110 117 109 98 101 114 34 58 34 49 34 44 34 116 105 116 108 101 34 58 34 116 101 115 116 34 125 44 34 49 34 58 123 34 110 117 109 98 101 114 34 58 34 49 34 44 34 116 105 116 108 101 34 58 34 116 101 115 116 34 125 44 34 50 34 58 123 34 110 117 109 98 101 114 34 58 34 49 34 44 34 116 105 116 108 101 34 58 34 116 101 115 116 34 125 44 34 51 34 58 123 34 110 117 109 98 101 114 34 58 34 49 34 44 34 116 105 116 108 101 34 58 34 116 101 115 116 34 125 44 34 52 34 58 123 34 110 117 109 98 101 114 34 58 34 49 34 44 34 116 105 116 108 101 34 58 34 116 101 115 116 34 125 44 34 53 34 58 123 34 110 117 109 98 101 114 34 58 34 49 34 44 34 116 105 116 108 101 34 58 34 116 101 115 116 34 125 44 34 54 34 58 123 34 110 117 109 98 101 114 34 58 34 49 34 44 34 116 105 116 108 101 34 58 34 116 101 115 116 34 125 44 34 55 34 58 123 34 110 117 109 98 101 114 34 58 34 49 34 44 34 116 105 116 108 101 34 58 34 116 101 115 116 34 125 44 34 56 34 58 123 34 110 117 109 98 101 114 34 58 34 49 34 44 34 116 105 116 108 101 34 58 34 116 101 115 116 34 125 44 34 57 34 58 123 34 110 117 109 98 101 114 34 58 34 49 34 44 34 116 105 116 108 101 34 58 34 116 101 115 116 34 125 125]
map[4:{1 test} 5:{1 test} 6:{1 test} 7:{1 test} 0:{1 test} 2:{1 test} 3:{1 test} 1:{1 test} 8:{1 test} 9:{1 test}]