2013-06-05 27 views
8

Przetwarzam json POST w Go, który zawiera tablicę obiektów zawierających 64-bitowe liczby całkowite. Podczas używania json.Unmarshal te wartości wydają się konwertowane na float64, co nie jest zbyt pomocne.Zachowaj wartości int64 podczas analizowania json w 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)) 

} 

Czy jest jakiś sposób, aby zachować oryginalne Int64 na wyjściu json.Unmarshal?

Go Playground of above code

Odpowiedz

18

Rozwiązanie 1

Można użyć Decoder i UseNumber do dekodowania numerów bez utraty:

Typ Number jest zdefiniowany następująco:

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

co oznacza, że ​​możesz łatwo ly przekonwertować go:

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 
} 

Rozwiązanie 2

Można również dekodować w specyficznej strukturze dostosowanej do swoich potrzeb:

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 
} 

Osobiście generalnie preferują takie rozwiązanie, które czuje się bardziej uporządkowany i łatwiejsze w utrzymaniu.

Uwaga

Mała uwaga jeśli używasz JSON, ponieważ aplikacja jest częściowo w JavaScript: JavaScript ma 64 bitów liczb całkowitych, ale tylko jeden typ numeru, który jest podwójnej precyzji IEEE 754 pływaka. Nie można przetworzyć tego JSON-a w JavaScript bez strat za pomocą standardowej funkcji parsowania.

Powiązane problemy