2014-07-09 12 views
48

Ich habe versucht, meine Go-Map in eine JSON-Zeichenfolge mit encoding/json Marshal zu konvertieren, aber es ergab sich eine leere Zeichenfolge.Convert Go Karte nach JSON

Hier ist mein 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) 
} 

Meine Ausgabe ist:

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}] 

[] 

Ich weiß wirklich nicht, wo ich falsch. Danke für Ihre Hilfe.

+12

Bitte downvote nicht ohne givi einen Kommentar. Ich denke, die Frage ist eine gute Frage (+1): Sie enthält den gesamten Code, sie enthält eine präzise Frage, die Ausgabe, ... Es ist völlig Thema und das OP hat sich viel Mühe gegeben, eine gute Frage zu stellen. Es ist wirklich eine Schande, die Downvotes hier zu haben! – topskip

+3

Das Problem rührt von der Tatsache her, dass das OP explizit den Fehler ignoriert, der die Frage sofort beantwortet hätte. – JimB

+2

Ich bin eindeutig gewissenhaft, ich lag falsch. Zwei Fehler in einer Frage. Sie können sicher sein, dass ich sie nicht wiederholen werde. – Cronos87

Antwort

53

Wenn Sie den Fehler erwischt hätte, hätte man gesehen haben:

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

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

Die Sache ist, dass Sie keine ganzen Zahlen als Schlüssel in JSON verwenden können; es ist verboten. Stattdessen können Sie diese Werte zuvor in Zeichenfolgen konvertieren, z. B. mit strconv.Itoa.

Sehen Sie diesen Beitrag für weitere Informationen: https://stackoverflow.com/a/24284721/2679935

+2

Hier können Sie sehen, wie die Typen map: http://golang.org/pkg/encoding/json/#Unmarshal Sie könnten stattdessen eine Scheibe verwenden, die einem JSON-Array zugeordnet wird. Auch: immer auf Fehler prüfen;) – seong

+0

Ich vermute, das Verhalten hat sich geändert. Siehe https://golang.org/pkg/encoding/json/#Unmarshal für "Der Schlüsseltyp der Map muss entweder ein String, ein Integer-Typ oder eine Encoding-Methode sein. TextMarshaler." –

+0

@AshharHasan Anscheinend hat es sich in Go 1.7 geändert (https://golang.org/doc/go1.7#encoding_json), aber es tut immer noch nicht das, was Sie erwarten würden: https://play.golang.org/p/ 0aFaQ_ByOk – julienc

20

Es Sie tatsächlich sagt, was falsch ist, aber Sie ignoriert es, weil Sie nicht der Fehler von json.Marshal zurückgegeben hat überprüfen.

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

JSON spec nichts außer Strings für Objektschlüssel unterstützen, während Sie Javascript um es nicht pingelig sein wird, ist es immer noch illegal ist.

Sie haben zwei Möglichkeiten:

1 Verwenden Sie map[string]Foo und den Index-String konvertieren (mit fmt.Sprint zum Beispiel):

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 einfach nur ein Stück verwenden (Javascript-Array):

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

+3

Sie haben Recht. Es ist ein schändlicher Fehler ... Ich weiß nicht wirklich, warum ich einen Int für einen JSON-Schlüssel verwendet habe ... Danke für Ihre Beispiele. – Cronos87