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

Go语言中如何动态修改结构体字段的JSON键适配不同API请求?

动态调整结构体字段的JSON键以适配不同请求类型

你可以通过为结构体实现自定义的MarshalJSON和UnmarshalJSON方法来解决这个问题,无需额外定义重复结构体或冗余字段,也能避免直接使用反射带来的复杂度。

实现方案

首先定义基础结构体,将Vat字段的默认JSON标签设为"-",避免标准库自动处理它:

type SilverfinCompany struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
    Vat  string `json:"-"` // 禁用默认序列化/反序列化
}

处理GET请求的反序列化(解析vat字段)

实现UnmarshalJSON方法,内部用临时结构体匹配GET响应的JSON结构,再把值映射到原结构体:

func (c *SilverfinCompany) UnmarshalJSON(data []byte) error {
    type tempCompany struct {
        ID   int    `json:"id"`
        Name string `json:"name"`
        Vat  string `json:"vat"`
    }

    var temp tempCompany
    if err := json.Unmarshal(data, &temp); err != nil {
        return err
    }

    c.ID = temp.ID
    c.Name = temp.Name
    c.Vat = temp.Vat
    return nil
}

处理POST/PATCH请求的序列化(输出vat_identifier字段)

实现MarshalJSON方法,用临时结构体匹配POST/PATCH所需的JSON结构,将原结构体的值填充进去后再序列化:

func (c SilverfinCompany) MarshalJSON() ([]byte, error) {
    type tempCompany struct {
        ID            int    `json:"id"`
        Name          string `json:"name"`
        VatIdentifier string `json:"vat_identifier"`
    }

    temp := tempCompany{
        ID:            c.ID,
        Name:          c.Name,
        VatIdentifier: c.Vat,
    }

    return json.Marshal(temp)
}

使用方式

和标准JSON操作完全一致,无需额外转换:

  • 解析GET响应:
    var company SilverfinCompany
    err := json.Unmarshal(getResponseBytes, &company)
    
  • 生成POST/PATCH请求体:
    requestBytes, err := json.Marshal(company)
    

为什么不推荐反射?

虽然理论上可以通过反射遍历结构体字段、手动映射键名,但这种方式代码晦涩,且反射操作存在一定性能损耗。自定义序列化/反序列化方法的可读性和可维护性更强,是Go社区处理此类场景的常规方案。


内容的提问来源于stack exchange,提问作者Anders Finn Jørgensen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 19:50:09