You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go RPC传输中如何保留非结构化JSON的整数类型?

在Go中JSON编解码全程保留整数类型的解决方案

针对你遇到的uint64类型在JSON编解码+RPC传输后转为float64、丢失原始类型的问题,有以下几种可行方案:

方案一:使用json.Number配合解码器UseNumber选项

Go标准库的encoding/json提供了json.Number类型和Decoder.UseNumber()方法,能将JSON数字以字符串形式暂存,避免自动转为float64,后续可还原为原始整数类型。

代码示例:

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

func main() {
    // 构建map时将uint64转为json.Number存储
    originalMap := map[string]interface{}{
        "config": map[string]interface{}{
            "port": json.Number(strconv.FormatUint(80, 10)),
        },
    }

    // 序列化JSON
    data, err := json.Marshal(originalMap)
    if err != nil {
        panic(err)
    }

    // 反序列化时启用UseNumber,保留数字的原始字符串形式
    var decodedMap map[string]interface{}
    decoder := json.NewDecoder(bytes.NewReader(data))
    decoder.UseNumber()
    if err = decoder.Decode(&decodedMap); err != nil {
        panic(err)
    }

    // 将json.Number转回uint64
    configMap, ok := decodedMap["config"].(map[string]interface{})
    if !ok {
        panic("config is not a map")
    }
    portNum, ok := configMap["port"].(json.Number)
    if !ok {
        panic("port is not a json.Number")
    }
    port, err := portNum.Uint64()
    if err != nil {
        panic(err)
    }

    fmt.Printf("Port值:%d,类型:%T\n", port, port) // 输出:Port值:80,类型:uint64
}

方案二:用自定义结构体替代map[string]interface{}

如果你的数据结构是可预知的,优先使用自定义结构体。结构体字段明确指定类型后,JSON编解码会严格遵循字段类型,完全避免interface{}导致的类型丢失问题。

代码示例:

import (
    "encoding/json"
    "fmt"
)

// 定义对应的数据结构体
type Config struct {
    Port uint64 `json:"port"`
}

type AppConfig struct {
    Config Config `json:"config"`
}

func main() {
    original := AppConfig{
        Config: Config{Port: 80},
    }

    // 序列化
    data, err := json.Marshal(original)
    if err != nil {
        panic(err)
    }

    // 反序列化回结构体
    var decoded AppConfig
    if err = json.Unmarshal(data, &decoded); err != nil {
        panic(err)
    }

    fmt.Printf("Port值:%d,类型:%T\n", decoded.Config.Port, decoded.Config.Port) // 输出:Port值:80,类型:uint64
}

方案三:使用第三方JSON序列化库

部分第三方JSON库提供了保留整数类型的配置,可直接将JSON数字解析为int64/uint64而非float64,无需手动处理json.Number。这类库通常API与标准库兼容,迁移成本低。


内容的提问来源于stack exchange,提问作者Abhishek Karigar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 08:50:08