Próbowałem przekonwertować moją mapę Go na ciąg json za pomocą encoding/json
Marshal, ale spowodowało to pusty ciąg.
Oto mój kod:
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)
}
Mój wynik to:
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}]
[]
Naprawdę nie wiem, gdzie się mylę. Dziękuję za pomoc.
Odpowiedzi:
Gdybyś złapał błąd, zobaczyłbyś to:
jsonString, err := json.Marshal(datas) fmt.Println(err) // [] json: unsupported type: map[int]main.Foo
Rzecz w tym, że nie możesz używać liczb całkowitych jako kluczy w JSON; to jest zabronione. Zamiast tego możesz wcześniej przekonwertować te wartości na ciągi, na przykład używając
strconv.Itoa
.Więcej informacji znajdziesz w tym poście: https://stackoverflow.com/a/24284721/2679935
źródło
W rzeczywistości mówi ci, co jest nie tak, ale zignorowałeś go, ponieważ nie sprawdziłeś błędu zwróconego przez
json.Marshal
.json: unsupported type: map[int]main.Foo
Specyfikacja JSON nie obsługuje niczego poza ciągami znaków dla kluczy obiektów, podczas gdy javascript nie będzie tego wybredny, nadal jest nielegalny.
Masz dwie możliwości:
1 Użyj
map[string]Foo
i przekonwertuj indeks na łańcuch (na przykład używając 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 Po prostu użyj wycinka (tablica 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
źródło
Ponieważ to pytanie zostało zadane / ostatnia odpowiedź, dodano obsługę typów kluczy innych niż łańcuchowe dla map dla json Marshal / UnMarshal poprzez użycie tutaj interfejsów TextMarshaler i TextUnmarshaler . Możesz po prostu zaimplementować te interfejsy dla swoich typów kluczy, a następnie działać zgodnie z oczekiwaniami.
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) }
Wynik:
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}]
źródło