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

无需修改Go结构体,实现int64/uint64与JS字符串的JSON互转

答案

可以实现,无需修改原有结构体定义或字段标签,推荐使用兼容标准库API的高性能JSON库json-iterator/go实现,无需侵入业务结构体,全局生效,实现成本最低。

实现步骤

  1. 安装依赖
go get github.com/json-iterator/go
  1. 全局注册int64、uint64类型的自定义编解码规则,完整代码示例如下:
package main

import (
	"fmt"
	"reflect"
	"strconv"
	"unsafe"

	jsoniter "github.com/json-iterator/go"
)

type Foo struct {
	A int64
	B uint64
	// 其他包含int64、uint64字段的结构体无需做任何修改
}

// 初始化阶段注册自定义编解码器,全局生效
func init() {
	int64Type := reflect.TypeOf(int64(0)).String()
	uint64Type := reflect.TypeOf(uint64(0)).String()
	// 注册int64序列化/反序列化规则
	jsoniter.RegisterTypeEncoder(int64Type, &int64AsStringEncoder{})
	jsoniter.RegisterTypeDecoder(int64Type, &int64AsStringDecoder{})
	// 注册uint64序列化/反序列化规则
	jsoniter.RegisterTypeEncoder(uint64Type, &uint64AsStringEncoder{})
	jsoniter.RegisterTypeDecoder(uint64Type, &uint64AsStringDecoder{})
}

// int64转JSON字符串序列化器
type int64AsStringEncoder struct{}
func (e *int64AsStringEncoder) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) {
	stream.WriteString(strconv.FormatInt(*(*int64)(ptr), 10))
}
func (e *int64AsStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
	return *(*int64)(ptr) == 0
}

// JSON字符串/数值转int64反序列化器
type int64AsStringDecoder struct{}
func (d *int64AsStringDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
	switch iter.WhatIsNext() {
	case jsoniter.StringValue:
		val, err := strconv.ParseInt(iter.ReadString(), 10, 64)
		if err != nil {
			iter.ReportError("parse int64", err.Error())
			return
		}
		*(*int64)(ptr) = val
	case jsoniter.NumberValue:
		*(*int64)(ptr) = iter.ReadInt64()
	default:
		iter.ReportError("parse int64", "unexpected value type")
	}
}

// uint64转JSON字符串序列化器
type uint64AsStringEncoder struct{}
func (e *uint64AsStringEncoder) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) {
	stream.WriteString(strconv.FormatUint(*(*uint64)(ptr), 10))
}
func (e *uint64AsStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
	return *(*uint64)(ptr) == 0
}

// JSON字符串/数值转uint64反序列化器
type uint64AsStringDecoder struct{}
func (d *uint64AsStringDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
	switch iter.WhatIsNext() {
	case jsoniter.StringValue:
		val, err := strconv.ParseUint(iter.ReadString(), 10, 64)
		if err != nil {
			iter.ReportError("parse uint64", err.Error())
			return
		}
		*(*uint64)(ptr) = val
	case jsoniter.NumberValue:
		*(*uint64)(ptr) = iter.ReadUint64()
	default:
		iter.ReportError("parse uint64", "unexpected value type")
	}
}

func main() {
	x := Foo{A: 1234567890987654, B: 987654321012345678}
	// 序列化,输出的int64/uint64自动带引号
	byt, err := jsoniter.Marshal(x)
	fmt.Println(err) // <nil>
	fmt.Println(string(byt)) // {"A":"1234567890987654","B":"987654321012345678"}

	// 反序列化,自动解析带引号的数值为对应int64/uint64类型
	err = jsoniter.Unmarshal([]byte(`{"A":"12345678901234567", "B":"98765432101234567"}`), &x)
	fmt.Println(err) // <nil>
	fmt.Printf("%#v\n", x) // main.Foo{A:12345678901234567, B:98765432101234567}
}

标准库实现方案

如果不想引入第三方依赖,可以基于标准库encoding/json封装自定义的Marshal/Unmarshal函数,通过反射遍历结构体所有字段,对int64、uint64类型做特殊转换处理即可,缺点是性能略低于第三方库实现,适合对性能要求不高的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 13:18:03