2013-06-05 21 views
8

64 bit tamsayılar içeren bir nesne dizisi içeren bir json POST işleniyor. Json.Unmarshal kullanırken bu değerleri çok yararlı olmayan bir float64 dönüştürülmüş gibi görünüyor.json ayrıştırma sırasında int64 değerlerini koru.

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

} 

Orijinal int64'ü json.Unmarshal çıktısında korumak için herhangi bir yolu var mı?

Go Playground of above code

cevap

18

Bir Decoder ve UseNumber kaybı olmadan numaralarını çözmek için kullanabileceğiniz bir 1

Çözüm:

Number tipi böyle tanımlanır:

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

yani yapabileceğin anlamına gelir ly dönüştürmek:

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 
} 

Çözüm 2

Ayrıca ihtiyaçlarına göre belli bir yapı halinde deşifre edebilir

:

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 
} 

Şahsen genellikle daha yapısal hissediyor bu çözümü tercih ve Bakımı daha kolay.

Dikkat

Başvurunuz JavaScript kısmen olduğu için JSON kullanırsanız küçük bir not: JavaScript hiçbir 64 bit tamsayı ancak IEEE-754 çift duyarlıklı şamandıra sadece bir numara türü bulunması. Böylece, bu JSON'u standart ayrıştırma işlevini kullanarak kayıp olmadan JavaScript'te ayrıştıramazsınız.