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

Go语言如何正确反序列化键为int类型的嵌套map

Go 中嵌套 map[int] 结构的 JSON 全层级反序列化方案

问题根源

JSON 标准规范明确要求对象的键必须为字符串类型,Go 标准库 encoding/json 的默认反序列化逻辑有如下规则:

  1. 显式声明目标变量为 map[int]interface{} 类型时,顶层键会自动尝试将 JSON 的字符串键转换为 int 类型
  2. 对于嵌套的 interface{} 类型值,遇到 JSON 对象时默认会反序列化为 map[string]interface{},不会自动做 int 键转换,这就是嵌套层键为 string 类型的根本原因。

解决方案:自定义反序列化逻辑实现全层级 int 键转换

你可以通过实现 json.Unmarshaler 接口,递归处理所有层级的 map 键转换,示例实现如下:

package main

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

// 自定义 int 键 map 类型,实现 json.Unmarshaler 接口
type IntKeyMap map[int]interface{}

func (m *IntKeyMap) UnmarshalJSON(data []byte) error {
	// 先按默认规则反序列化为 string 键 map
	var raw map[string]interface{}
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}
	*m = make(IntKeyMap)
	// 遍历处理所有键值对
	for kStr, v := range raw {
		// 字符串键转 int
		kInt, err := strconv.Atoi(kStr)
		if err != nil {
			return fmt.Errorf("非法int格式键: %s", kStr)
		}
		// 递归处理嵌套对象
		switch nestedVal := v.(type) {
		case map[string]interface{}:
			var nestedMap IntKeyMap
			nestedData, _ := json.Marshal(nestedVal)
			if err := json.Unmarshal(nestedData, &nestedMap); err != nil {
				return err
			}
			(*m)[kInt] = nestedMap
		default:
			(*m)[kInt] = nestedVal
		}
	}
	return nil
}

func main() {
	buf := []byte(`{"1":"one","2":{"3":"three"}}`)
	var obj IntKeyMap
	if err := json.Unmarshal(buf, &obj); err != nil {
		panic(err)
	}
	// 输出验证:main.IntKeyMap{1:"one", 2:main.IntKeyMap{3:"three"}}
	fmt.Printf("%#v\n", obj)
}

注意事项

  • 如果业务场景中存在非 int 格式的字符串键,可根据需求调整错误处理逻辑,比如忽略非法键、保留为 string 类型
  • 上述递归实现对任意深度的嵌套结构都适用,所有层级的 map 都会自动转为 IntKeyMap 类型,键均为 int 类型

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 11:06:03