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

为什么Golang的json.Unmarshal处理含"e"和"E"字段的JSON时会出错?

问题1 反序列化报错的原因

Go标准库encoding/json包匹配JSON键与结构体json标签的逻辑分为两步:

  • 优先进行精确匹配,即JSON键与标签值完全一致才会绑定字段
  • 精确匹配失败后,会 fallback 到大小写不敏感的模糊匹配

你定义的message结构体仅声明了json:"e"标签的string类型字段,反序列化{"e": "foo", "E": 1}时:

  1. JSON键e精确匹配到EventType字段,成功赋值为"foo"
  2. JSON键E找不到精确匹配的标签,触发模糊匹配后命中json:"e"对应的EventType字段,此时尝试将数字1赋值给string类型字段,就抛出了类型不匹配的错误。

而messageUppercaseE结构体同时声明了json:"E"标签,JSON键E会优先精确匹配到对应的uint64类型字段,不会触发模糊匹配,因此反序列化正常。


问题2 原生实现反序列化的方案

不需要引入第三方库,可任选以下两种方案实现:

方案1:补充占位字段承接大写E键值

在message结构体中补充对应E键的字段,避免触发模糊匹配即可,不需要的字段后续直接忽略使用即可:

type message struct {
    EventType string `json:"e"`
    // 补充占位字段,精确匹配JSON的E键,不需要可直接忽略该字段值
    UppercaseE uint64 `json:"E"`
}

如果不需要保留E键的值,也可以将占位字段的类型定义为interface{}兼容任意值类型。

方案2:自定义反序列化逻辑(无多余字段)

如果不想在结构体中增加多余字段,可以为message类型实现UnmarshalJSON方法,自定义解析逻辑:

import (
    "encoding/json"
    "fmt"
)

type message struct {
    EventType string
}

func (m *message) UnmarshalJSON(data []byte) error {
    // 用map承接所有JSON键值,避免模糊匹配问题
    var tmp map[string]interface{}
    if err := json.Unmarshal(data, &tmp); err != nil {
        return err
    }
    // 单独提取e字段做类型校验和赋值
    eVal, eOk := tmp["e"]
    if !eOk {
        return fmt.Errorf("missing required field e")
    }
    eStr, strOk := eVal.(string)
    if !strOk {
        return fmt.Errorf("field e is not string type")
    }
    m.EventType = eStr
    return nil
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 05:48:03