新闻中心

解析包含字符串编码整数和 Null 值的 JSON 数据:Go 语言实践

2025-11-16
浏览次数:
返回列表

解析包含字符串编码整数和 null 值的 json 数据:go 语言实践

本文介绍了在 Go 语言中解析包含字符串编码整数和 Null 值的 JSON 数据时可能遇到的问题,并提供了一种使用自定义 Unmarshaller 的解决方案,以确保正确处理 Null 值,避免解析错误。

在 Go 语言中使用 encoding/json 包解析 JSON 数据时,如果 JSON 数据中包含以字符串形式编码的整数,并且这些字段可能包含 null 值,则可能会遇到一些问题。默认情况下,json.Unmarshal 函数在遇到 null 值时,可能会保留之前解析的值,而不是将其设置为零值。这会导致解析结果不符合预期。

问题描述

假设我们有以下 JSON 数据:

[
  {"price": "1"},
  {"price": null},
  {"price": "2"}
]

我们希望将其解析为 Product 结构体的切片,其中 Price 字段是整数类型,并且使用 json:",string,omitempty" tag 将其指定为字符串编码。

package main

import (
    "encoding/json"
    "log"
)

type Product struct {
    Price int `json:",string,omitempty"`
}

func main() {
    data := `
[
  {"price": "1"},
  {"price": null},
  {"price": "2"}
]
`

    var products []Product
    if err := json.Unmarshal([]byte(data), &products); err != nil {
        log.Printf("%#v", err)
    }
    log.Printf("%#v", products)

}

运行上述代码,我们会发现输出结果不符合预期:

[]main.Product{main.Product{Price:1}, main.Product{Price:1}, main.Product{Price:2}}

可以看到,当 price 字段为 null 时,Price 字段的值并没有被设置为零值,而是保留了之前解析的值。

解决方案:自定义 Unmarshaller

为了解决这个问题,我们可以使用自定义 Unmarshaller。通过实现 json.Unmarshaler 接口,我们可以自定义 JSON 数据的解析逻辑,从而正确处理 null 值。

Zyro AI Background Remover Zyro AI Background Remover

Zyro推出的AI图片背景移除工具

Zyro AI Background Remover 145 查看详情 Zyro AI Background Remover

以下是使用自定义 Unmarshaller 的示例代码:

package main

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

type Product struct {
    Price int `json:",string,omitempty"`
}

func (p *Product) UnmarshalJSON(b []byte) error {
    m := map[string]interface{}{} // 修改为 interface{}
    err := json.Unmarshal(b, &m)
    if err != nil {
        return err
    }

    if price, ok := m["price"]; ok {
        if price == nil { // 检查是否为 nil
            p.Price = 0
            return nil
        }
        priceStr, ok := price.(string)
        if !ok {
            // 如果不是 string 类型,尝试转换为 string
            priceFloat, ok := price.(float64)
            if ok {
                priceStr = strconv.FormatFloat(priceFloat, 'f', 0, 64)
            } else {
                return nil // 或者返回错误,取决于你的需求
            }
        }
        p.Price, _ = strconv.Atoi(priceStr)
    }
    return nil
}

func main() {
    data := `
[
  {"price": "1"},
  {"price": null},
  {"price": "2"}
]
`

    var products []Product
    if err := json.Unmarshal([]byte(data), &products); err != nil {
        log.Printf("%#v", err)
    }
    log.Printf("%#v", products)

}

在这个示例中,我们首先将 JSON 数据解析为一个 map[string]interface{}。然后,我们检查 price 字段是否存在。如果存在,并且其值为 nil,则将 Price 字段设置为 0。否则,将其转换为字符串并使用 strconv.Atoi 函数将其解析为整数。

注意: 需要将map[string]string{} 修改为 map[string]interface{}{},因为 json.Unmarshal 会将 null 解析为 nil。如果仍然使用 map[string]string{},则无法正确处理 null 值。同时,增加类型断言,处理 price 字段为 float64 的情况。

运行上述代码,我们会得到期望的输出结果:

[]main.Product{main.Product{Price:1}, main.Product{Price:0}, main.Product{Price:2}}

总结

当 JSON 数据中包含字符串编码的整数和 null 值时,使用默认的 json.Unmarshal 函数可能会导致解析错误。通过实现自定义 Unmarshaller,我们可以自定义 JSON 数据的解析逻辑,从而正确处理 null 值,避免解析错误。这种方法可以确保在遇到 null 值时,将相应的字段设置为零值,从而得到符合预期的解析结果。

以上就是解析包含字符串编码整数和 Null 值的 JSON 数据:Go 语言实践的详细内容,更多请关注其它相关文章!


# 转换为  # 南昌湾里网站优化推广  # 南京seo陈小欢  # 淘宝做网站推广的靠谱吗  # seo网站上线  # 广州教育网站推广  # 阜新网站优化流程  # 哈尔滨关键词竞价排名  # 打造外贸网站建设价格  # 网站建设制作定做  # 深圳儿童网站优化有用吗  # 在这个  # 资源管理  # js  # 不符合  # 我们可以  # 为零  # 正确处理  # 加载  # 将其  # 自定义  # ai  # 编码  # go  # json 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 在命令行怎么运行html项目_命令行运行html项目方法【教程】  J*aScript数组对象转换:按指定键分组与值收集  批改网学生版PC登录 批改网官网登录系统入口  Golang并发任务中错误如何聚合_Golang goroutine error收集方式  双系统安装时,如何设置默认启动系统? msconfig命令了解一下!  Win11输入法不见了怎么办_Windows11恢复语言栏显示方法  Python异步编程实践:使用Binance API构建实时交易数据流  漫蛙MANWA漫画主页官方入口 漫蛙漫画最新在线阅读地址  深入理解J*a合成构造器:何时以及为何阻止其生成  React项目中导航栏Logo自适应布局:避免裁剪与布局溢出  从OpenAI API响应中高效提取生成文本  妖精动漫免费平台 妖精动漫官网资源观看网址  荣耀Play7T运行卡顿解决_荣耀Play7T性能优化  优化Log4j2控制台输出性能:解决异步日志瓶颈  实现全屏滚动与导航点:专业教程  QQ邮箱网页版入口 QQ邮箱官方邮箱登录通道  Golang如何安装Swagger工具_GoSwagger文档生成环境  lar*el怎么安全地存储和获取配置文件中的敏感信息_lar*el敏感信息安全存储方法  qq游戏免费畅玩入口_qq游戏电脑版快速启动  Python实现多节点属性重叠度分析教程  ACG动漫视频网入口 ACG动漫*免费正版观看地址  深入理解Go语言中的指针类型:以*string为例  汽水音乐车机版横屏版7.1 汽水音乐车机版横屏版下载入口  HTML5原生日期选择器与jQuery UI:实现日期选择器的联动与程序化控制  深入理解J*a链表中的IPosition接口与使用  JUnit5/Mockito:优雅测试内部依赖与异常处理的实践  Go语言HTML解析:利用Goquery精准获取指定元素内容  QQ网页版官方账号入口 QQ网页版网页版登录指南  Go语言中Map存储的结构体如何调用指针方法:深入解析与实践  快手官方唯一登录入口 谨防山寨钓鱼网站  Yandex官方入口网址 Yandex俄罗斯搜索引擎最新在线地址  漫蛙manwa2最新登录网址_漫蛙manwa2手机网页版入口  怎么在mac上运行html代码_mac运行html代码方法【指南】  使用 Pandas 高效处理 .dat 文件:字符清理与数据计算  新三国志曹操传110级星符试炼夏侯渊极难攻略  Excel Power Pivot如何处理XML数据源 构建高级数据模型  c++ 获取系统当前时间 c++时间戳获取方法  葱吃多了会怎样 葱吃多了会伤胃吗  b站怎么删除评论_b站评论管理与删除操作  蛙漫漫画免费阅读入口_蛙漫官方正版无广告纯净版  如何为你的Composer包编写自动化测试_集成PHPUnit到Composer的scripts工作流  Golang如何实现Web接口签名验证_Golang Web接口签名校验开发方法  汽水音乐网页版使用入口_汽水音乐电脑版播放指南  解决Django多数据库/多Schema环境下外键迁移问题  Win11文件资源管理器卡顿怎么修 Win11重置资源管理器进程优化响应速度【修复方法】  在哪找SublimeJ远程工具_SFTP插件配置教程  Python大型XML文件高效流式解析教程  J*a里如何使用forEach遍历Map_Map遍历方法说明  《刺客信条4:黑旗》重制版新细节曝光:无缝加载 地图更细致!  C++如何实现一个装饰器模式_C++设计模式之动态地给对象添加额外职责 

搜索