2013-06-05 21 views
8

sto elaborazione POST json in Go che contiene una matrice di oggetti che contengono numeri interi a 64 bit. Quando si utilizza json.Unmarshal questi valori sembrano essere convertiti in un float64 che non è molto utile.preservare valori Int64 quando analizza json in Go

body := []byte(`{"tags":[{"id":4418489049307132905},{"id":4418489049307132906}]}`) 

var dat map[string]interface{} 
if err := json.Unmarshal(body, &dat); err != nil { 
    panic(err) 
} 

tags := dat["tags"].([]interface{}) 

for i, tag := range tags { 

    fmt.Println("tag: ", i, " id: ", tag.(map[string]interface{})["id"].(int64)) 

} 

C'è un modo per preservare l'int64 originale nell'output di json.Unmarshal?

Go Playground of above code

risposta

18

Soluzione 1

È possibile utilizzare un Decoder e UseNumber per decodificare i numeri senza perdita:

Il tipo Number si definisce in questo modo:

// A Number represents a JSON number literal. 
type Number string 

il che significa che puoi easi LY convertirlo:

package main 

import (
    "encoding/json" 
    "fmt" 
    "bytes" 
    "strconv" 
) 

func main() { 
    body := []byte("{\"tags\":[{\"id\":4418489049307132905},{\"id\":4418489049307132906}]}") 
    dat := make(map[string]interface{}) 
    d := json.NewDecoder(bytes.NewBuffer(body)) 
    d.UseNumber() 
    if err := d.Decode(&dat); err != nil { 
     panic(err) 
    } 
    tags := dat["tags"].([]interface{}) 
    n := tags[0].(map[string]interface{})["id"].(json.Number) 
    i64, _ := strconv.ParseUint(string(n), 10, 64) 
    fmt.Println(i64) // prints 4418489049307132905 
} 

Soluzione 2

È inoltre possibile decodificare in una struttura specifica su misura per le vostre esigenze:

package main 

import (
    "encoding/json" 
    "fmt" 
) 

type A struct { 
    Tags []map[string]uint64 // "tags" 
} 

func main() { 
    body := []byte("{\"tags\":[{\"id\":4418489049307132905},{\"id\":4418489049307132906}]}") 
    var a A 
    if err := json.Unmarshal(body, &a); err != nil { 
     panic(err) 
    } 
    fmt.Println(a.Tags[0]["id"]) // logs 4418489049307132905 
} 

Personalmente io in genere preferisco questa soluzione, che si sente più strutturato e più facile da mantenere.

Attenzione

Una piccola nota se si utilizza JSON perché l'applicazione è in parte in JavaScript: JavaScript non ci sono numeri interi a 64 bit, ma solo un tipo di numero, che è l'IEEE754 float doppia precisione. Quindi non sareste in grado di analizzare questo JSON in JavaScript senza perdita usando la funzione di analisi standard.

Problemi correlati