Heim >Backend-Entwicklung >Golang >Das Geheimnis der JSON-Konvertierung von IntTo Float64
Die Arbeit mit JSON kann einfach und klar klingen, Sie haben eine Struktur, Sie können sie in JSON ändern – eine allgemein einheitliche Sprache und zurück zu Ihrer Struktur. Einfach, oder? ?
Nun ja, aber das ist so lange, bis Sie auf ein seltsames Verhalten der Marshal-/Unmarshal-Funktionen stoßen.
Alles begann, als ich versuchte, die codierte Nutzlast von einem JWT-Token zu lesen. Unten finden Sie ein Beispiel, das das Problem veranschaulicht
package main import ( "encoding/json" "fmt" ) type User struct { ID int64 `json:"id"` PostIDs []int64 `json:"post_ids"` } func main() { u := User{ ID: 1, PostIDs: []int64{1, 2, 3}, } b, err := json.Marshal(u) if err != nil { panic(err) } m := make(map[string]interface{}) if err = json.Unmarshal(b, &m); err != nil { panic(err) } userID, ok := m["id"].(int64) fmt.Printf("id: %d\nOk:%t\n", userID, ok) fmt.Println() // spliter postIDs, ok := m["id"].([]int64) fmt.Printf("post_ids: %v\nOk:%t\n", postIDs, ok) }
Nur das Marshallen und Unmarshaling der Struktur, es wird also erwartet, dass sie den gleichen Wert zurückgibt!
Leider ist das nicht passiert, der obige Code gibt aus
// Result id: 0 Ok:false post_ids: [] Ok:false
Als ich diese Ausgabe gesehen habe, habe ich ? Das Problem könnte bei Typkonvertierungen liegen, daher habe ich nachgesehen, welche Typen diese Schnittstellen haben
fmt.Printf("id: %T\n", m["id"]) fmt.Printf("post_ids: %T\n", m["post_ids"])
// Result id: float64 post_ids: []interface {}
Wie wir sehen können, hat JSON int64 als float64 geparst, was zu Problemen beim Lesen der Daten führte.
Es gibt eigentlich zwei Möglichkeiten, dieses Problem zu beheben
Verwenden Sie Typzusicherungen von float64. Beachten Sie, dass []interface{} nicht sofort []float64 zugeordnet werden kann, daher müssen wir jedes Element iterieren und konvertieren
// Parse UserID userID, _ := m["id"].(float64) fmt.Printf("id: %f\n", userID) fmt.Println() // spliter // Parse PostIDs postIDsArr, _ := m["post_ids"].([]interface{}) postIDs := make([]int64, len(postIDsArr)) for i, v := range postIDsArr { id, _ := v.(float64) // NOTICE: direct conversion to int64 won't work here! postIDs[i] = int64(id) } fmt.Printf("post_ids: %v\n", postIDs)
// Result id: 1.000000 post_ids: [1 2 3]
Parsen Sie es zurück in eine Struktur
b, err = json.Marshal(m) // m = map[string]interface{} if err != nil { panic(err) } var u2 User if err := json.Unmarshal(b, &u2); err != nil { panic(err) } fmt.Println(u2.ID) fmt.Println(u2.PostIDs)
Natürlich denken Sie vielleicht: Warum sollten wir überhaupt Lösung 01 verwenden, ist Lösung 02 nicht besser?
Nun, es kommt darauf an, Sie möchten nicht immer eine Struktur erstellen, um ein einzelnes Attribut aus einer Struktur zu lesen, daher lautet die richtige Antwort: Es kommt darauf an!
Ich denke, das ist alles für den heutigen Artikel. Ich wünschte, du hättest etwas Neues gelernt, mein Gopher-Kollege?.
Das obige ist der detaillierte Inhalt vonDas Geheimnis der JSON-Konvertierung von IntTo Float64. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!