2013-06-05 34 views
8

Tôi đang xử lý một POST json trong Go có chứa một mảng các đối tượng chứa các số nguyên 64 bit. Khi sử dụng json.Unmarshal các giá trị này dường như được chuyển đổi thành float64 mà không phải là rất hữu ích.giữ lại các giá trị int64 khi phân tích cú pháp json trong 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ó cách nào để bảo toàn int64 ban đầu trong đầu ra của json.Unmarshal không?

Go Playground of above code

Trả lời

18

Giải pháp 1

Bạn có thể sử dụng một DecoderUseNumber để giải mã số của bạn mà không mất:

Loại Number được định nghĩa như thế này:

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

có nghĩa là bạn có thể easi ly chuyển đổi nó:

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 
} 

Giải pháp 2

Bạn cũng có thể giải mã thành một cấu trúc cụ thể phù hợp với nhu cầu của bạn:

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 
} 

Cá nhân tôi thường thích giải pháp này mà cảm thấy có cấu trúc hơn và dễ bảo trì hơn.

Thận trọng

Một lưu ý nhỏ nếu bạn sử dụng JSON vì ứng dụng của bạn là một phần trong JavaScript: JavaScript không có 64 bit số nguyên nhưng chỉ có một số loại, đó là IEEE754 độ chính xác kép phao. Vì vậy, bạn sẽ không thể phân tích cú pháp JSON này bằng JavaScript mà không bị mất khi sử dụng hàm phân tích cú pháp chuẩn.

Các vấn đề liên quan