我试图将我的Go地图转换为带有encoding/jsonMarshal 的json字符串,但它导致了一个空字符串.
这是我的代码:
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)
}
Run Code Online (Sandbox Code Playgroud)
我的输出是:
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}]
[]
Run Code Online (Sandbox Code Playgroud)
我真的不知道我哪里错了.谢谢您的帮助.
jul*_*enc 82
如果你发现错误,你会看到这个:
jsonString, err := json.Marshal(datas)
fmt.Println(err)
// [] json: unsupported type: map[int]main.Foo
Run Code Online (Sandbox Code Playgroud)
问题是你不能在JSON中使用整数作为键; 这是被禁止的.相反,您可以事先将这些值转换为字符串,例如使用strconv.Itoa.
有关更多详细信息,请参阅此帖子:https://stackoverflow.com/a/24284721/2679935
One*_*One 25
它实际上告诉你什么是错的,但你忽略了它,因为你没有检查从中返回的错误json.Marshal.
json: unsupported type: map[int]main.Foo
除了对象键的字符串之外,JSON规范不支持任何内容,而javascript对它不会很挑剔,它仍然是非法的.
您有两种选择:
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)
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
自从提出/上次回答这个问题以来,已通过使用此处的TextMarshaler和TextUnmarshaler接口添加了对 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)
}
Run Code Online (Sandbox Code Playgroud)
输出:
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}]
Run Code Online (Sandbox Code Playgroud)
随着时间的推移,这种行为已经发生了改变。我正在使用 go v1.16.5,我可以愉快地将 int 类型作为 JSON 键传递。我现在尝试了同样的问题,我可以看到下面的结果。textMarshaler和textUnmarshaler接口添加了非字符串键的类型转换。欲了解更多信息,您可以访问此https://golang.org/pkg/encoding/json/#Marshal
type Foo struct {
Number int `json:"number"`
Title string `json:"title"`
}
datas := make(map[int]Foo)
for i := 0; i < 5; i++ {
datas[i] = Foo{Number: 1, Title: "test"}
}
jsonString, _ := json.Marshal(datas)
fmt.Println("Datasets Result : ", datas)
fmt.Println("Marshal Datasets Result : ", string(jsonString), err)
m := make(map[int]Foo)
err = json.Unmarshal(jsonString, &m)
if err != nil {
panic(err)
}
fmt.Println("Unmarshal JSON Result : ", m)
Run Code Online (Sandbox Code Playgroud)
输出:
Datasets Result map : [0:{1 test} 1:{1 test} 2:{1 test} 3:{1 test} 4:{1 test}]
Marshal Datasets Result : {"0":{"number":1,"title":"test"},"1":{"number":1,"title":"test"},"2":{"number":1,"title":"test"},"3":{"number":1,"title":"test"},"4":{"number":1,"title":"test"}} <nil>
Unmarshal JSON Result : map[0:{1 test} 1:{1 test} 2:{1 test} 3:{1 test} 4:{1 test}]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
87766 次 |
| 最近记录: |