Heim >Backend-Entwicklung >Golang >Das Geheimnis der JSON-Konvertierung von IntTo Float64

Das Geheimnis der JSON-Konvertierung von IntTo Float64

WBOY
WBOYOriginal
2024-09-03 13:20:191164Durchsuche

The Mystery Of JSON Conversion Of 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.

Problem ?

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

? Lösung 01 (Harter Weg)

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]

? Lösung 02 (einfache Möglichkeit)

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn