2013-06-05 12 views
8

64ビット整数を含むオブジェクトの配列を含むGoのjson POSTを処理しています。 json.Unmarshalを使用している場合、これらの値はfloat64に変換されているようですが、これはあまり役に立ちません。Goの構文解析時にint64の値を保持する

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

} 

json.Unmarshalの出力に元のint64を保存する方法はありますか?

Go Playground of above code

答えて

18

あなたがDecoderUseNumberを失うことなく、あなたの番号を解読するために使用できる1

ソリューション:

Numberタイプは次のように定義されています

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

あなたは簡単にできることを意味するLYそれを変換:

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 
} 

ソリューション2

あなたはまた、あなたのニーズに合わせた具体的な構造にデコードすることができます:私は、一般的に、より構造化されたと感じ、このソリューションを好む個人的に

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 
} 

と維持しやすい

注意

アプリケーションはJavaScriptで一部があるので、あなたはJSONを使用している場合、小さなノート:JavaScriptが何の64ビット整数が、IEEE754倍精度浮動小数点数で一つだけの数の種類を、持っていません。したがって、標準の解析関数を使用することで、このJSONをJavaScriptで解析することができなくなります。