Maison > développement back-end > Golang > le corps du texte

Le mystère de la conversion JSON de IntTo Float64

WBOY
Libérer: 2024-09-03 13:20:19
original
1039 Les gens l'ont consulté

The Mystery Of JSON Conversion Of IntTo Float64

Travailler avec JSON peut sembler simple et clair, vous avez une structure, vous pouvez la changer en JSON — Un langage général unifié et revenir à votre structure. Simple, non ? ?

Eh bien, oui, mais c'est jusqu'à ce que vous rencontriez un comportement étrange de la part des fonctions Marshal/Unmarshal.

Problème ?

Tout a commencé lorsque j'essayais de lire la charge utile codée à partir d'un jeton JWT. Vous trouverez ci-dessous un exemple qui illustre le problème

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)
}
Copier après la connexion

Il suffit de marshaler et de démarshaler la structure, donc elle devrait renvoyer la même valeur !

Malheureusement, cela ne s'est pas produit, le code ci-dessus affiche

// Result
id: 0
Ok:false

post_ids: []
Ok:false
Copier après la connexion

Une fois que j'ai vu cette sortie, je ? le problème pourrait venir des conversions de types, alors je suis allé vérifier quels types ont ces interfaces

    fmt.Printf("id: %T\n", m["id"])
    fmt.Printf("post_ids: %T\n", m["post_ids"])
Copier après la connexion
// Result
id: float64
post_ids: []interface {}
Copier après la connexion

Comme nous pouvons le voir, JSON a analysé int64 comme float64, ce qui entraîne des problèmes lors de la lecture des données.

Il existe en fait 2 façons de résoudre ce problème

? Solution 01 (difficile)

Utilisez les assertions de type de float64, notez que []interface{} ne peut pas être mappée immédiatement sur []float64, nous devons donc itérer chaque élément et le convertir

        // 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)
Copier après la connexion
// Result
id: 1.000000

post_ids: [1 2 3]
Copier après la connexion

? Solution 02 (facile)

Analysez-le en une structure

    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)
Copier après la connexion

Bien sûr, vous pourriez penser, pourquoi devrions-nous même utiliser la solution 01, la solution 02 n'est-elle pas meilleure ?

Eh bien, cela dépend, vous ne voulez pas toujours créer une structure pour lire un seul attribut d'une structure, donc la bonne réponse est -- Cela dépend !

Je pense que c'est tout pour l'article d'aujourd'hui, j'aimerais que tu aies appris quelque chose de nouveau, mon cher Gopher ?.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!