How Can I Parse Integers and Floats Accurately from JSON in Golang?

Linda Hamilton
Release: 2024-11-24 09:12:10
Original
352 people have browsed it

How Can I Parse Integers and Floats Accurately from JSON in Golang?

Parsing Integers as Integers and Floats as Floats in JSON Using Golang

In a Golang application that receives a stream of JSON records for forwarding to a data store (InfluxDB), it's crucial to preserve the original data type of integer and float values to avoid type conflicts and ensure successful write operations. While the Ruby JSON parser effortlessly performs this task, the encoding/json package in Golang initially parses all numbers as floats, potentially leading to type mismatch and write failures.

A Workaround Using Custom JSON Values

To replicate the behavior of the Ruby JSON parser, one approach is to utilize the generic Go mechanism for custom JSON values. In this method, JSON numbers are represented as byte arrays (json.RawMessage) and parsed using strconv.ParseInt and strconv.ParseFloat. This allows for accurate conversion of integers and floats:

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

func main() {
    str := `{"a":123,"b":12.3,"c":"123","d":"12.3","e":true}`
    var raw map[string]json.RawMessage
    err := json.Unmarshal([]byte(str), &raw)
    if err != nil {
        panic(err)
    }
    parsed := make(map[string]interface{}, len(raw))
    for key, val := range raw {
        s := string(val)
        i, err := strconv.ParseInt(s, 10, 64)
        if err == nil {
            parsed[key] = i
            continue
        }
        f, err := strconv.ParseFloat(s, 64)
        if err == nil {
            parsed[key] = f
            continue
        }
        var v interface{}
        err = json.Unmarshal(val, &v)
        if err == nil {
            parsed[key] = v
            continue
        }
        parsed[key] = val
    }
    for key, val := range parsed {
        fmt.Printf("%T: %v %v\n", val, key, val)
    }
}
Copy after login

Output:

int64: a 123 
float64: b 12.3 
string: c 123 
string: d 12.3 
bool: e true 
Copy after login

Using the json.Number Type

An alternative approach involves using the Go json.Number type, which allows for efficient parsing of both integers and floats directly from the JSON data:

import (
    "encoding/json"
    "fmt"
    "strings"
)

func main() {
    str := `{"a":123,"b":12.3,"c":"123","d":"12.3","e":true}`
    var parsed map[string]interface{}
    d := json.NewDecoder(strings.NewReader(str))
    d.UseNumber()
    err := d.Decode(&parsed)
    if err != nil {
        panic(err)
    }
    for key, val := range parsed {
        n, ok := val.(json.Number)
        if !ok {
            continue
        }
        if i, err := n.Int64(); err == nil {
            parsed[key] = i
            continue
        }
        if f, err := n.Float64(); err == nil {
            parsed[key] = f
            continue
        }
    }
    for key, val := range parsed {
        fmt.Printf("%T: %v %v\n", val, key, val)
    }
}
Copy after login

Output:

int64: a 123
float64: b 12.3
string: c 123
string: d 12.3
bool: e true
Copy after login

These methods provide effective solutions for preserving the original data type of integers and floats during JSON parsing in Golang, ensuring accurate and reliable data handling.

The above is the detailed content of How Can I Parse Integers and Floats Accurately from JSON in Golang?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template