Я попытался преобразовать свою карту Go в строку json с помощью encoding/json
Marshal, но в результате получилась пустая строка.
Вот мой код:
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)
}
Мой вывод:
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}]
[]
Я действительно не знаю, в чем я ошибаюсь. Спасибо за помощь.
Ответы:
Если бы вы поймали ошибку, вы бы увидели это:
jsonString, err := json.Marshal(datas) fmt.Println(err) // [] json: unsupported type: map[int]main.Foo
Дело в том, что вы не можете использовать целые числа в качестве ключей в JSON; запрещено. Вместо этого вы можете заранее преобразовать эти значения в строки, например, используя
strconv.Itoa
.Подробнее см. В этом сообщении: https://stackoverflow.com/a/24284721/2679935
источник
На самом деле он говорит вам, что не так, но вы проигнорировали его, потому что не проверяли ошибку, возвращенную из
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)
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
источник
Поскольку этот вопрос был задан вопрос / последний ответил, поддержка для не строковых типов ключевых для карт для JSON маршалом / распаковать было добавлено за счет использования TextMarshaler и TextUnmarshaler интерфейсов здесь . Вы можете просто реализовать эти интерфейсы для своих ключевых типов, и тогда все
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) }
Выход:
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}]
источник