Go语言中JSON的反序列化规则
Unmarshal 解析
func Unmarshal(data []byte, v any) error
Unmarshal 解析 JSON 编码的数据,并将结果存储在 v 指向的值中。如果 v 为 nil 或不是指针,Unmarshal 返回一个 InvalidUnmarshalError 错误。
Unmarshal 使用与 Marshal 相反的编码,根据需要分配 maps、slices 和 pointers,附加以下规则:
为了将 JSON 反序列化为指针,Unmarshal 首先处理 JSON 为 JSON 字面值 null 的情况。在那种情况下,Unmarshal 将指针设置为 nil。否则,Unmarshal 会将 JSON 反序列化为指针所指向的值。如果指针为 nil,Unmarshal 为它分配一个新值。
为了将 JSON 反序列化为实现了 Unmarshaler 接口的值,Unmarshal 会调用该值的 UnmarshalJSON 方法,包括当输入是一个 JSON null 时。否则,如果该值实现了 encoding.TextUnmarshaler 并且输入是一个 JSON 引号字符串,Unmarshal 使用该字符串的未引用形式调用该值的 UnmarshalText 方法。
为了将 JSON 反序列化为结构体,Unmarshal 将传入的对象键与 Marshal 使用的键匹配(是结构字段名还是它的标签),首选精确匹配,但也接受不区分大小写的匹配。默认情况下,没有对应结构字段的对象键将被忽略(参见 Decoder.DisallowUnknownFields 作为一种选择)。
为了将 JSON 反序列化为接口值,Unmarshal 在接口值中存储以下之一:
- bool,对应 JSON 布尔值
- float64,对应 JSON 数字
- string,对应 JSON 字符串
- []interface{},对应 JSON 数组
- map[string]interface{},对应 JSON 对象
- nil,对应 JSON null
为了将 JSON 数组反序列化为切片,Unmarshal 将切片长度重置为零,然后将每个元素追加到切片。作为一个特殊情况,为了将一个空的 JSON 数组反序列化为切片,Unmarshal 用一个新的空切片替换该切片。
为了将 JSON 数组反序列化为 Go 数组,Unmarshal 将 JSON 数组元素解码为相应的 Go 数组元素。如果 Go 数组小于 JSON 数组,额外的 JSON 数组元素将被丢弃。如果 JSON 数组小于 Go 数组,额外的 Go 数组元素将设置为零值。
为了将 JSON 对象反序列化为 map,Unmarshal 首先确定要使用的 map。如果 map 为 nil,Unmarshal 分配一个新的 map。否则,Unmarshal 重用现有的 map,保留现有的条目。然后,Unmarshal 将来自 JSON 对象的键值对存储在 map 中。map 的键类型必须是任何字符串类型,整数,实现 json.Unmarshaler,或实现 encoding.TextUnmarshaler。
如果 JSON 编码的数据包含语法错误,Unmarshal 返回一个 SyntaxError。
如果 JSON 值不适用于给定的目标类型,或者 JSON 数字溢出目标类型,Unmarshal 跳过该字段并尽其所能完成反序列化。如果没有遇到更严重的错误,Unmarshal 返回描述最早的这种错误的 UnmarshalTypeError。无论如何,不能保证在有问题的字段之后的所有剩余字段都会被反序列化到目标对象中。
JSON null 值反序列化为接口、map、指针或切片时,通过将该 Go 值设置为 nil 来完成。因为在 JSON 中,null 经常用来表示“不存在”,所以将 JSON null 反序列化为任何其他 Go 类型对该值没有影响,也不会产生错误。
当反序列化带引号的字符串时,无效的 UTF-8 或无效的 UTF-16 替代对不被视为错误。相反,它们被替换为 Unicode 替代字符 U+FFFD。
Go语言中JSON的反序列化规则的更多相关文章
- GO语言中json与map的转换
直接上代码(需要引入encoding/json包) // 当前程序的包名 package main // 导入其它的包 import ( "encoding/json" " ...
- .Net使用Newtonsoft.Json.dll(JSON.NET)对象序列化成json、反序列化json示例教程
JSON作为一种轻量级的数据交换格式,简单灵活,被很多系统用来数据交互,作为一名.NET开发人员,JSON.NET无疑是最好的序列化框架,支持XML和JSON序列化,高性能,免费开源,支持LINQ查询 ...
- C语言中,头文件和源文件的关系(转)
简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析阶段 3.编译阶段,首先编译成纯汇编语句, ...
- C语言中void*详解及应用
void在英文中作为名词的解释为“空虚:空间:空隙”:而在C语言中,void被翻译为“无类型”,相应的void *为“无类型指针”.void似乎只有“注释”和限制程序的作用,当然,这里的“注释”不是为 ...
- (七)C语言中的void 和void 指针类型
许多初学者对C中的void 和void 的指针类型不是很了解.因此常常在使用上出现一些错误,本文将告诉大家关于void 和void 指针类型的使用方法及技巧. 1.首先,我们来说说void 的含义: ...
- 转:C语言中的static变量和C++静态数据成员(static member)
转自:C语言中的static变量和C++静态数据成员(static member) C语言中static的变量:1).static局部变量 a.静态局部变量在函数内定义,生存期为整个程序 ...
- C语言中.h和.c文件解析(很精彩)
C语言中.h和.c文件解析(很精彩) 简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析 ...
- C语言中.h和.c文件解析
整理自C语言中.h和.c文件解析(很精彩) Part.1(林锐<高质量C/C++编程>) 通过头文件来调用库功能.在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的 ...
- C/C++语言中const的用法
1. const 在C和C++中的区别 C++中的const正常情况下是看成编译期的常量,编译器并不为const分配空间,只是在编译的时候将期值保存在名字表中,并在适当的时候折合在代码中. 所 ...
- 转-C语言中.h和.c文件解析
C语言中.h和.c文件解析(很精彩) 简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词 ...
随机推荐
- docker部署gitlab CI/CD (二)终篇:部署gitlab runner和添加gitlab-ci.yml文件 终极踩坑版
关于gitlab部署的教程还好,有的看,但到了cicd环节,简直痛苦面具,教程虽多,但断断续续,先不说大部分都是只截取片段,让人云里雾里,不会的看不懂,懂的不需要看,根据步骤跑不起来不说,改了一堆,完 ...
- django的部署在centos
虚拟环境 #virtualenv是一个创建独立python环境的工具 sudo pip install virtualenv #virtualenvwrapper将所有的虚拟环境统一管理,留意安装路径 ...
- FnOnce , FnMut <RUST>
FnOnce 1 #[lang = "fn_once"] 2 #[must_use = "closures are lazy and do nothing unless ...
- C++面试八股文:std::deque用过吗?
某日二师兄参加XXX科技公司的C++工程师开发岗位第26面: 面试官:deque用过吗? 二师兄:说实话,很少用,基本没用过. 面试官:为什么? 二师兄:因为使用它的场景很少,大部分需要性能.且需要自 ...
- 免费好用的录屏工具 —— EVCapture --九五小庞
下载地址:https://wwfv.lanzoue.com/b022u08ib密码:acdu 1,简介 使用过很多种屏幕录像软件,最终这个软件留下来存到我的工具宝库. 因为界面非常简单友好,功能也很好 ...
- 《最新出炉》系列初窥篇-Python+Playwright自动化测试-5-元素定位大法-上篇
1.简介 说到元素定位,小伙伴或者童鞋们肯定会首先想到 selenium 的八大元素定位大法.同理Playwright也有自己的元素定位的方法.今天就给小伙伴或者童鞋们讲解和分享一下Playwrigh ...
- ERP导出(自定义格式表格)R报表开发代码
按照正常流程新建程序,画面修改上传,程序下载修改 导入JAVA包,在global.import下 IMPORT com IMPORT JAVA java.net.URL IMPORT JAVA org ...
- 【调制解调】ISB 独立边带调幅
说明 学习数字信号处理算法时整理的学习笔记.同系列文章目录可见 <DSP 学习之路>目录,代码已上传到 Github - ModulationAndDemodulation.本篇介绍 IS ...
- Redis的设计与实现(6)-压缩列表
压缩列表 (ziplist) 是列表键和哈希键的底层实现之一. 当一个列表键只包含少量列表项, 并且每个列表项要么就是小整数值, 要么就是长度比较短的字符串, 那么 Redis 就会使用压缩列表来做列 ...
- 在Java项目中使用redisson实现分布式锁
Redisson自定义注解实现分布式锁 在Java项目中使用Redission自定义注解实现分布式锁: 添加Redission依赖项:在项目的pom.xml中添加Redission依赖项: <d ...