Home > Backend Development > Golang > How Can I Preserve Data Types When Parsing JSON in Go?

How Can I Preserve Data Types When Parsing JSON in Go?

DDD
Release: 2024-11-25 02:46:10
Original
730 people have browsed it

How Can I Preserve Data Types When Parsing JSON in Go?

Preserving Data Types in JSON Parsing

One challenge encountered when parsing JSON data in Golang is the automatic conversion of numeric values to floats. This can lead to inconsistencies with the original data, especially when dealing with integer values.

To address this issue, there are several techniques to preserve data types during JSON parsing.

Custom JSON Values

One approach is to utilize the custom JSON value mechanism provided by Go. This involves creating a custom type that implements the json.Marshaler and json.Unmarshaler interfaces. By overriding the MarshalJSON and UnmarshalJSON methods, you can control how numeric values are handled during serialization and deserialization.

Go json.Number

Another option is to use the json.Number type introduced in Go 1.8. By default, numeric values in JSON are parsed as float64. However, by using json.Number and calling the Int64 or Float64 methods, you can explicitly convert the number to an integer or floating-point value, respectively.

Example Implementation

package main

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

type MyJSONNumber struct {
    json.Number
}

func (mn *MyJSONNumber) MarshalJSON() ([]byte, error) {
    if n, err := strconv.Atoi(string(mn.Number)); err == nil {
        return []byte(strconv.Itoa(n)), nil
    }
    return []byte(mn.Number), nil
}

func (mn *MyJSONNumber) UnmarshalJSON(b []byte) error {
    if n, err := strconv.Atoi(string(b)); err == nil {
        mn.Number = strconv.Itoa(n)
        return nil
    }
    mn.Number = string(b)
    return nil
}

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)
        jnum := MyJSONNumber{json.Number(s)}
        n, err := jnum.Int64()
        if err == nil {
            parsed[key] = n
            continue
        }
        f, err := jnum.Float64()
        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

The above is the detailed content of How Can I Preserve Data Types When Parsing JSON in Go?. 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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template