„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Das Geheimnis der JSON-Konvertierung von IntTo Float64

Das Geheimnis der JSON-Konvertierung von IntTo Float64

Veröffentlicht am 02.11.2024
Durchsuche:709

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 ist 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 Marshalling und Unmarshaling der Struktur, daher wird erwartet, dass sie denselben Wert zurückgibt!

Leider ist dies nicht passiert, der obige Code gibt Folgendes 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, also 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?.

Freigabeerklärung Dieser Artikel ist abgedruckt unter: https://dev.to/aehelaly/the-mystery-of-json-conversion-of-int64-to-float64-5eof?1 Bei Verstößen wenden Sie sich bitte an [email protected] um es zu löschen
Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3