0

0

如何在 Go 中正确解析嵌套 JSON 数据

碧海醫心

碧海醫心

发布时间:2026-01-29 15:11:01

|

833人浏览过

|

来源于php中文网

原创

如何在 Go 中正确解析嵌套 JSON 数据

本文详解 go 语言中使用 encoding/json 解析含多层嵌套结构(如嵌套对象映射)的 json 数据,重点解决字段标签误用、匿名结构体嵌套声明不当导致的反序列化失败问题,并提供可直接运行的结构体定义与最佳实践。

在 Go 中解析嵌套 JSON 时,常见错误是将 JSON 对象(如 "ports": { "tcp": [...], "udp": [...] })错误地映射为字符串字段或未正确绑定 JSON 标签,从而触发 json: cannot unmarshal object into Go value of type string 等 panic。根本原因在于:Go 的 json.Unmarshal 要求结构体字段类型必须与 JSON 值类型严格匹配,且嵌套对象需通过嵌套结构体 + 正确 json tag 显式声明

以下是一个修复后的完整示例,清晰展示了如何定义结构体以准确映射嵌套 JSON:

package main

import (
    "fmt"
    "encoding/json"
)

type Data struct {
    Ports struct {
        Tcp []int `json:"tcp"`
        Udp []int `json:"udp"`
    } `json:"ports"` // ⚠️ 关键:外层匿名结构体整体绑定 "ports" 字段
    Protocols []string `json:"protocols"`
}

func main() {
    jsonStr := `{
        "ports": {
            "udp": [1, 30],
            "tcp": [100, 1023]
        },
        "protocols": ["tcp", "udp"]
    }`

    var data Data
    if err := json.Unmarshal([]byte(jsonStr), &data); err != nil {
        fmt.Printf("解析失败: %v\n", err)
        return
    }

    fmt.Printf("TCP 端口: %v\n", data.Ports.Tcp)   // 输出: [100 1023]
    fmt.Printf("UDP 端口: %v\n", data.Ports.Udp)   // 输出: [1 30]
    fmt.Printf("协议列表: %v\n", data.Protocols)   // 输出: [tcp udp]
}

关键要点说明

笔头写作
笔头写作

AI为论文写作赋能,协助你从0到1。

下载
  • Ports 字段必须是结构体类型(不能是 string 或其他基础类型),因为其对应 JSON 中的 object
  • 匿名结构体内部字段(Tcp/Udp)需显式添加 json:"tcp" / json:"udp" 标签,确保与 JSON 键名精确匹配(大小写敏感);
  • 外层 Ports 字段自身也需带 json:"ports" 标签——这是最容易被忽略的一点:它告诉解码器将 JSON 中的 "ports" 键值对整体映射到该匿名结构体;
  • 数值数组建议使用 []int(而非 []float64),除非 JSON 明确包含浮点数;Go 的 JSON 解码器能自动将整数字面量转为 int(只要不溢出)。

⚠️ 常见陷阱提醒

  • 若将 Ports 定义为 P string \json:"ports"`(如原问题代码),解码器会尝试把整个{ "tcp": [...], "udp": [...] }` 对象赋给字符串,必然失败;
  • 忘记为嵌套结构体加外层 json tag,会导致该字段被忽略(零值);
  • 字段名首字母小写(如 tcp []int)会使字段不可导出,json 包无法访问,导致解码静默失败(字段保持零值)。

总结:处理嵌套 JSON 的核心原则是——“JSON 对象 → Go 结构体”,逐层对齐层级与类型,并为每一级字段正确配置 json tag。合理利用匿名结构体可避免过度定义冗余类型,提升代码简洁性与可维护性。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

182

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

229

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

343

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

209

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

395

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

240

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

193

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

438

2025.06.17

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

1

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 8.6万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号