"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > Le mystère de la conversion JSON de IntTo Float64

Le mystère de la conversion JSON de IntTo Float64

Publié le 2024-11-02
Parcourir:281

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 illustrant 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)
}

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

Malheureusement, cela ne s'est pas produit, le code ci-dessus génère

// Result
id: 0
Ok:false

post_ids: []
Ok:false

Une fois que j'ai vu cette sortie, j'ai ? 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"])
// Result
id: float64
post_ids: []interface {}

Comme nous pouvons le voir, JSON a analysé int64 en tant que 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)
// Result
id: 1.000000

post_ids: [1 2 3]

? 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)

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 vous appreniez quelque chose de nouveau, mon cher Gopher ?.

Déclaration de sortie Cet article est reproduit sur : https://dev.to/aehelaly/the-mystery-of-json-conversion-of-int64-to-float64-5eof?1 En cas de violation, veuillez contacter [email protected] pour le supprimer
Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3