You need to enable JavaScript to run this app. Go 语言转换 JSON 结构时出现切片索引越界(index out of range)报错
优惠活动
大模型
产品
解决方案
定价
更多

Go 语言转换 JSON 结构时出现切片索引越界(index out of range)报错

报错核心原因

触发index out of range [0] with length 0的逻辑链路非常明确:

  • 循环赋值时直接通过索引访问新版结构体的Labels切片,但该切片是结构体零值,初始长度为0,没有可索引的实体元素。第一次取索引[0]时,自然会触发长度越界。
  • 原逻辑默认新版切片已经预分配了和旧版数组等长的元素,但实际上Go中值类型结构体虽然会自动初始化嵌套的结构体字段,对应的切片字段依然是长度为0的空切片,不存在可供索引的位置。
  • 附带的配置错误:定义Labels元素的Value字段时,json标签漏了双引号,写的json:value无法被标准json包正确识别,后续序列化的字段名会不符合预期。
具体修复步骤
  • 替换原有的硬索引赋值逻辑:不直接通过索引往空切片写值,而是根据旧版Niveau数组的实际长度,动态构造对应长度的Labels切片,再赋值给新版结构体的对应字段。
  • 把原有的nil判断替换成更稳妥的长度判断len(xxx) > 0,避免长度为0但非nil的切片进入无效逻辑。
  • 修正结构体字段的json标签格式,给标签值加上双引号。
  • 把重复定义的匿名Label结构体抽成独立类型,减少重复代码、降低出错概率。
修改后的可运行代码
// 抽离重复定义的标签结构体
type LabelItem struct {
    Value string `json:"value"`
}

type AnnotV1 struct {
    Uuid string `json:"uuid"`
    Data struct {
        Niveau1 []string `json:"Niveau1"`
        Niveau2 []string `json:"Niveau2"`
        Niveau3 []string `json:"Niveau3"`
    } `json:"data"`
    User string `json:"user"`
}

type AnnotV2 struct {
    Uuid string `json:"uuid"`
    Annotation struct {
        Classif struct {
            Niveau1 struct {
                Labels []LabelItem `json:"labels"`
            } `json:"Niveau1"`
            Niveau2 struct {
                Labels []LabelItem `json:"labels"`
            } `json:"Niveau2"`
            Niveau3 struct {
                Labels []LabelItem `json:"labels"`
            } `json:"Niveau3"`
        } `json:"classifications"`
    } `json:"annotation"`
    User string `json:"user"`
}

func convert(oldAnnots []AnnotV1) (newAnnots []AnnotV2) {
    for _, element := range oldAnnots {
        var newAnnot AnnotV2
        newAnnot.User = element.User
        newAnnot.Uuid = element.Uuid

        // Niveau1赋值逻辑
        if len(element.Data.Niveau1) > 0 {
            labels := make([]LabelItem, 0, len(element.Data.Niveau1))
            for _, annotVal := range element.Data.Niveau1 {
                labels = append(labels, LabelItem{Value: annotVal})
            }
            newAnnot.Annotation.Classif.Niveau1.Labels = labels
        }

        // Niveau2赋值逻辑
        if len(element.Data.Niveau2) > 0 {
            labels := make([]LabelItem, 0, len(element.Data.Niveau2))
            for _, annotVal := range element.Data.Niveau2 {
                labels = append(labels, LabelItem{Value: annotVal})
            }
            newAnnot.Annotation.Classif.Niveau2.Labels = labels
        }

        // Niveau3赋值逻辑
        if len(element.Data.Niveau3) > 0 {
            labels := make([]LabelItem, 0, len(element.Data.Niveau3))
            for _, annotVal := range element.Data.Niveau3 {
                labels = append(labels, LabelItem{Value: annotVal})
            }
            newAnnot.Annotation.Classif.Niveau3.Labels = labels
        }

        newAnnots = append(newAnnots, newAnnot)
    }
    return
}

额外注意:你提供的新版JSON示例存在层级缩进问题——示例中Niveau3被嵌在了Niveau2的字段内部,但你定义的结构体中三个Niveau字段是平级放在classifications下的,需要根据实际的新版JSON结构调整嵌套层级,避免后续json序列化/反序列化匹配不上字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.28 18:54:08