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

Go语言解析JSON生成指定层级Map的错误排查求助

Go分组JSON数据时Map结构不符合预期的问题排查与修复

问题描述

原始JSON结构

{
   "items": [
      {"pkg": "0", "pin": "0", "item": "0"},
      {"pkg": "1", "pin": "1", "item": "1"},
      {"pkg": "0", "pin": "2", "item": "2"},
      {"pkg": "1", "pin": "3", "item": "3"},
      {"pkg": "0", "pin": "4", "item": "4"},
      {"pkg": "1", "pin": "5", "item": "5"},
      {"pkg": "0", "pin": "6", "item": "6"},
      {"pkg": "1", "pin": "7", "item": "7"},
      {"pkg": "0", "pin": "8", "item": "8"},
      {"pkg": "1", "pin": "9", "item": "9"},
      {"pkg": "0", "pin": "10", "item": "10"},
      {"pkg": "1", "pin": "11", "item": "11"},
      {"pkg": "0", "pin": "12", "item": "12"},
      {"pkg": "1", "pin": "13", "item": "13"},
      {"pkg": "0", "pin": "14", "item": "14"},
      {"pkg": "1", "pin": "15", "item": "15"},
      {"pkg": "0", "pin": "16", "item": "16"},
      {"pkg": "1", "pin": "17", "item": "17"},
      {"pkg": "0", "pin": "18", "item": "18"},
      {"pkg": "1", "pin": "19", "item": "19"},
      {"pkg": "0", "pin": "20", "item": "20"},
      {"pkg": "1", "pin": "21", "item": "21"},
      {"pkg": "0", "pin": "22", "item": "22"},
      {"pkg": "1", "pin": "23", "item": "23"},
      {"pkg": "0", "pin": "24", "item": "24"},
      {"pkg": "1", "pin": "25", "item": "25"},
      {"pkg": "0", "pin": "26", "item": "26"},
      {"pkg": "1", "pin": "27", "item": "27"},
      {"pkg": "0", "pin": "28", "item": "28"},
      {"pkg": "1", "pin": "29", "item": "29"},
      {"pkg": "0", "pin": "30", "item": "30"},
      {"pkg": "1", "pin": "31", "item": "31"},
      {"pkg": "0", "pin": "0", "item": "32"},
      {"pkg": "1", "pin": "1", "item": "33"},
      {"pkg": "0", "pin": "2", "item": "34"},
      {"pkg": "1", "pin": "3", "item": "35"},
      {"pkg": "0", "pin": "4", "item": "36"},
      {"pkg": "1", "pin": "5", "item": "37"},
      {"pkg": "0", "pin": "6", "item": "38"},
      {"pkg": "1", "pin": "7", "item": "39"},
      {"pkg": "0", "pin": "8", "item": "40"},
      {"pkg": "1", "pin": "9", "item": "41"}
     ]
}

用于解析的Go代码

package basics

import (
   "encoding/json"
   "fmt"
   "io/ioutil"
   "strconv"
)
type NNodes struct {
    Items []NodeItem `json:"items"`
} 

type NodeItem struct {
    Pkg string `json:"pkg"`
    Pin string `json:"pin"`
    Item string `json:"item"`
}

func parser() {
     data, _ := ioutil.ReadFile("list.json")
     var result NNodes 
     var pkg, pin, item  int
     json.Unmarshal(data, &result)
     foobar := make(map[int]map[int][]int)
     siblings := make(map[int][]int)
     for _, value := range result.items {
         if pkg, err = strconv.Atoi(value.Pkg); err != nil {
            break 
         }
         if pin, err = strconv.Atoi(value.Pin); err != nil {
             break
         }
         if item, err = strconv.Atoi(value.Item); err != nil {
              break
         }
         siblings[pin] = append(siblings[pin], item)
         foobar[pkg] = siblings
    }
    fmt.Println(foobar)
} 

当前输出

map[0:map[0:[0 32] 1:[1 33] 2:[2 34] 3:[3 35] 4:[4 36] 5:[5 37] 6:[6 38] 7:[7 39] 8:[8 40] 9:[9 41] 10:[10] 11:[11] 12:[12] 13:[13] 14:[14] ... ]

期望输出

map[0:map[0:[0,32] 2:[2,34] 4:[4,36] 6:[6,38]... ]
map[1:map[1:[1,33] 3:[3,35] 5:[5,37] 7:[7,39]... ]

错误原因

核心问题是所有pkg共用了同一个siblings map。在Go中,map是引用类型,每次执行foobar[pkg] = siblings时,都是把同一个map的地址赋值给不同的pkg键,导致所有pkg对应的子map都是同一个实例,最终所有pin的数据都混在一起。

另外还有两个次要问题:

  • 错误处理过于粗暴:只要有一个转换失败就直接break,应该记录错误并跳过当前条目,而不是终止整个循环
  • 结构体字段名:result.items应该是result.Items(结构体里定义的是首字母大写的Items,Go的JSON解析依赖导出字段)

修正后的代码

package basics

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

type NNodes struct {
	Items []NodeItem `json:"items"`
}

type NodeItem struct {
	Pkg  string `json:"pkg"`
	Pin  string `json:"pin"`
	Item string `json:"item"`
}

func parser() {
	data, err := ioutil.ReadFile("list.json")
	if err != nil {
		fmt.Printf("read file error: %v\n", err)
		return
	}

	var result NNodes
	err = json.Unmarshal(data, &result)
	if err != nil {
		fmt.Printf("unmarshal json error: %v\n", err)
		return
	}

	foobar := make(map[int]map[int][]int)

	for _, value := range result.Items { // 修正字段名:Items而非items
		pkg, err := strconv.Atoi(value.Pkg)
		if err != nil {
			fmt.Printf("invalid pkg: %s, error: %v\n", value.Pkg, err)
			continue // 转换失败时跳过当前条目,而非终止循环
		}

		pin, err := strconv.Atoi(value.Pin)
		if err != nil {
			fmt.Printf("invalid pin: %s, error: %v\n", value.Pin, err)
			continue
		}

		item, err := strconv.Atoi(value.Item)
		if err != nil {
			fmt.Printf("invalid item: %s, error: %v\n", value.Item, err)
			continue
		}

		// 检查当前pkg是否已有对应的子map,没有则创建新的
		if _, ok := foobar[pkg]; !ok {
			foobar[pkg] = make(map[int][]int)
		}
		// 向当前pkg的子map中添加item
		foobar[pkg][pin] = append(foobar[pkg][pin], item)
	}

	fmt.Println(foobar)
}

关键修复点

  • 移除全局的siblings map,改为针对每个pkg动态创建子map:处理某个pkg时,先检查foobar中是否已存在该pkg对应的子map,不存在则初始化一个新的
  • 修正结构体字段访问:使用result.Items(首字母大写,确保字段可被JSON解析)
  • 优化错误处理:转换失败时跳过当前条目,而非直接终止循环,同时添加错误日志便于调试
  • 避免引用类型共享问题,每个pkg拥有独立的子map,数据不会交叉污染

内容的提问来源于stack exchange,提问作者Niranjan M.R

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 01:24:30