Go的json序列化:Marshal与Unmarshal

news2024/11/26 14:38:47

5ba88c1021e8f3e164153f324ae03cb0.jpeg

简介

Json(Javascript Object Nanotation)是一种数据交换格式,常用于前后端数据传输。任意一端将数据转换成json 字符串,另一端再将该字符串解析成相应的数据结构,如string类型,strcut对象等。


1.Json Marshal:将数据编码成json字符串

type Stu struct {
    Name  string `json:"name"`
    Age   int    //来源公众号:「码农编程进阶笔记」
    sex   string  //小写的字段不可导出,所以无法序列化
    Class *Class `json:"class"`
}

type Class struct {
    Name  string
    Grade int
}

func main() {
    //实例化一个数据结构,用于生成json字符串
    stu := Stu{
        Name: "张三",
        Age:  18,
        sex:  "男",
    }

    //指针变量
    cla := new(Class)
    cla.Name = "1班"
    cla.Grade = 3
    stu.Class=cla

    jsonStu, err := json.Marshal(stu)
    if err != nil {
        fmt.Println(err.Error())
    }
    // jsonStu是[]byte类型,转化为string类型便于查看
    fmt.Println(string(jsonStu))
}

结果

{"name":"张三","Age":18,"class":{"Name":"1班","Grade":3}}

从结果中可以看出

  • • 只要是可导出成员(变量首字母大写),都可以转成json。踩坑点:因成员变量sex是不可导出的,故无法转成json。

  • • 如果变量打上了json标签,如Name旁边的 json:"name" ,那么转化成的json key就用该标签“name”,否则取变量名作为key,如“Age”,“HIgh”。

  • • bool类型也是可以直接转换为json的value值。Channel, complex 以及函数不能被编码json字符串。当然,循环的数据结构也不行,它会导致marshal陷入死循环。

  • • 指针变量,编码时自动转换为它所指向的值,如cla变量。(当然,不传指针,Stu struct的成员Class如果换成Class struct类型,效果也是一模一样的。只不过指针更快,且能节省内存空间。)

最后,强调一句:json编码成字符串后就是纯粹的字符串了。

总结: 将map或者结构体传入json.Marshal函数,生成json,返回类型会[]byte


2.Json Unmarshal:将json字符串解码到相应的数据结构

type StuRead struct {
    Name  interface{} `json:"name"`
    Age   interface{}
    HIgh  interface{}
    sex   interface{}
    Class interface{} `json:"class"`
    Test  interface{}
}

type Class struct {
    Name  string
    Grade int
}

func main() {    //json字符中的"引号,需用\进行转义,否则编译出错
    //json字符串沿用上面的结果,但对key进行了大小的修改,并添加了sex数据
    data:="{\"name\":\"张三\",\"Age\":18,\"high\":true,\"sex\":\"男\",\"CLASS\":{\"naME\":\"1班\",\"GradE\":3}}"
    str:=[]byte(data)

    //1.Unmarshal的第一个参数是json字符串,第二个参数是接受json解析的数据结构。
    //第二个参数必须是指针,否则无法接收解析的数据,如stu仍为空对象StuRead{}
    //2.可以直接stu:=new(StuRead),此时的stu自身就是指针      //来源公众号:「码农编程进阶笔记」    stu:=StuRead{}
    err:=json.Unmarshal(str,&stu)

    //解析失败会报错,如json字符串格式不对,缺"号,缺}等。
    if err!=nil{
        fmt.Println(err)
    }
    fmt.Println(stu)
}

结果:

{张三 18 true <nil> map[naME:1班 GradE:3] <nil>}

总结:

  • • json字符串解析时,需要一个“接收体”接受解析后的数据,且Unmarshal时接收体必须传递指针。否则解析虽不报错,但数据无法赋值到接受体中。如这里用的是StuRead{}接收,也可以使用map进行接收。

  • • 解析时,接收体可自行定义。json串中的key自动在接收体中寻找匹配的项进行赋值。匹配规则是:

  • • 先查找与key一样的json标签,找到则赋值给该标签对应的变量(如Name)。没有json标签的,就从上往下依次查找变量名与key一样的变量,如Age。或者变量名忽略大小写后与key一样的变量。如HIgh,Class。第一个匹配的就赋值,后面就算有匹配的也忽略。(前提是该变量必需是可导出的,即首字母大写)。不可导出的变量无法被解析(如sex变量,虽然json串中有key为sex的k-v,解析后其值仍为nil,即空值)

*当接收体中存在json串中匹配不了的项时,解析会自动忽略该项,该项仍保留原值。如变量Test,保留空值nil。

*你一定会发现,变量Class貌似没有解析为我们期待样子。因为此时的Class是个interface{}类型的变量,而json串中key为CLASS的value是个复合结构,不是可以直接解析的简单类型数据(如“张三”,18,true等)。所以解析时,由于没有指定变量Class的具体类型,json自动将value为复合结构的数据解析为map[string]interface{}类型的项。也就是说,此时的struct Class对象与StuRead中的Class变量没有半毛钱关系,故与这次的json解析没有半毛钱关系。

注意:若转换为结构体之后想继续操作序列化之后的字段,此时interface{}需要转化为对应的类型,使用v.(type),type为需要转化的类型。如interface.(string),使用需谨慎,类型不对会引发panic。

若结构体里有的字段不想序列化,而想保留原json,办法还是有的,我们可以将该变量定义为 json.RawMessage类型,保留原json可以进行二次解析。

type StuRead struct {
    Name  interface{}
    Age   interface{}
    HIgh  interface{}
    Class json.RawMessage `json:"class"` //注意这里
}

f084c1e3cb214816a1e07898b81d6bac.jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1173285.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2、Sentinel基本应用限流规则(2)

2.2.1 是什么 Sentinel 是阿里中间件团队开源的&#xff0c;面向分布式服务架构的轻量级高可用流量控制组件&#xff0c;主要以流量为切入点&#xff0c;从流量控制、熔断降级、系统负载保护等多个维度来帮助用户保护服务的稳定性。 2.2.2 基本概念 • 资源 (需要被保护的东西…

分享81个工作总结PPT,总有一款适合您

分享81个工作总结PPT&#xff0c;总有一款适合您 PPT下载链接&#xff1a;https://pan.baidu.com/s/13hyrlZo2GhRoQjI-6z31-w?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理更不易。知识付…

二叉搜索树专题1 二叉查找树的建立

题目&#xff1a; 样例&#xff1a; 输入 6 5 2 3 6 1 8 输出 5 2 1 3 6 8 思路&#xff1a; 二叉搜索树的建立&#xff0c;需要了解二叉搜索树的性质。 二叉搜索树的性质 左孩子结点&#xff1a; 比根节点小 右孩子结点&#xff1a; 比根节点大 根据所给的序列进行按序…

【数据结构】排序算法复杂度 及 稳定性分析 【图文详解】

排序算法总结 前言[ 一 ] 小数据基本排序算法&#xff08;1&#xff09;冒泡排序&#xff08;2&#xff09;直接插入排序 [ 二 ] &#xff08;由基本排序衍生的用作&#xff09;处理大数据处理排序&#xff08;1&#xff09;堆排序&#xff08;2&#xff09;希尔排序 [ 三 ] 大…

Leetcode-88 合并两个有序数组

使用内置排序函数&#xff0c;时间复杂度On^2 class Solution {public void merge(int[] nums1, int m, int[] nums2, int n) {int j0,im;while(j<n){nums1[i]nums2[j];}Arrays.sort(nums1);} }新建一个临时数组用于放排序后的元素&#xff0c;再将临时数组赋值给nums1&…

Technology strategy Pattern 学习笔记3-Creating the Strategy-Industry context

Creating the Strategy-Industry context 1 SWOT 1.1 create steps 1.与内部各方沟通 了解企业的人、流程和技术&#xff0c;包括与其它企业的不同了解哪些创新可以做竞争者及市场信息企业可以支撑的类似业务 按SWOT四象限分类&#xff0c;先做列表后放入象限 1.2 四象限…

C++ 代码实例:多项式除法简单计算工具

文章目录 前言代码仓库代码说明核心片段 结果总结参考资料作者的话 前言 C 代码实例&#xff1a;多项式除法简单计算工具。 代码仓库 yezhening/Programming-examples: 编程实例 (github.com)Programming-examples: 编程实例 (gitee.com) 代码 说明 由于代码篇幅较多&#…

AI:57-基于机器学习的番茄叶部病害图像识别

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…

linux之按键中断

查看原理图确认引脚 可以看到按键有两个&#xff0c;分别对应GPIO5_1和GPIO4_14 配置pinctrl&#xff0c;配置成GPIO模式 1.使用官方工具&#xff0c;配置下引脚 2.将生成的代码复制到设备树里 创建设备节点 生成二进制设备树文件 在工具链表下使用 make dtbs 或者使…

“宽带中国”工具变量—海拔标准差数据集

参照刘传明&#xff08;2020&#xff09;、金环&#xff08;2021&#xff09;、胡浩然&#xff08;2023&#xff09;等的做法&#xff0c;将地级市-海拔标准差数据&#xff0c;作为“宽带中国”试点政策的工具变量 ➤相关性&#xff1a;地形起伏度会影响网络基础设施建设&…

asp.net 创建docker容器

首先创建asp.net web api 创建完成后如下图 添加docker支持 添加docker支持 添加linux docker支持

SOEM源码解析——ecx_writeeeprom(写EEPROM)

0 工具准备 1.SOEM-master-1.4.0源码1 ecx_writeeeprom函数总览 /** Write EEPROM to slave bypassing cache.&#xff1a;绕过从站缓存写EEPROM数据* param[in] context context struct 句柄* param[in] slave Slave number 从站序号* param[in] eeproma (WORD) …

Voice vlan、ICMP、单臂路由、mux-vlan

目录 一&#xff0c;Voice VLAN Voice vlan配置命令 一&#xff0c;问&#xff1a;已知网络中一台服务器的IP地址&#xff0c;如何找到这太服务器在哪台交换机的哪个接口上​编辑 思路&#xff1a; 二&#xff0c;ICMP协议 三&#xff0c;ICMP案例分析​编辑 四&#xf…

学习c++的第十一天

目录 继承和派生 基类 & 派生类 访问控制和继承 派生类的构造函数 派生类的析构函数 继承类型 多继承 重载运算符和重载函数 函数重载 运算符重载 可重载运算符/不可重载运算符 运算符重载实例 继承和派生 先来说继承&#xff0c;这与现实生活中的继承意思差不…

2023年电工杯数学建模B题人工智能对大学生学习影响的评价求解全过程论文及程序

2023年电工杯数学建模 B题 人工智能对大学生学习影响的评价 原题再现&#xff1a; 人工智能简称AI&#xff0c;最初由麦卡锡、明斯基等科学家于1956年在美国达特茅斯学院开会研讨时提出。   2016年&#xff0c;人工智能AlphaGo 4:1战胜韩国围棋高手李世石&#xff0c;期后波…

【亚马逊云科技产品测评】活动征文|亚马逊云科技AWS之EC2详细测评

引言 &#xff08;授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道&#xff09; 在当前的数字化时代&#xff0c;云服务已…

小饭店点餐系统,小餐馆点餐怎么方便,操作简单的酒店点单软件

小饭店点餐系统&#xff0c;小餐馆点餐怎么方便&#xff0c;操作简单的酒店点单软件 今天给大家分享是 佳易王酒店点餐管理系统软件V16.0版本&#xff0c;点餐界面如下图&#xff0c; 1、开台的桌子醒目显示&#xff0c;结账后或没有开台的桌子为灰色显示。 2、多种点餐方式…

Pytho入门教程之Python运行的三种方式

文章目录 一、交互式编程二、脚本式编程三、方式三关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料六、Python兼职渠道 一、交互式编…

AMD老电脑超频及性能提升方案及实施

收拾电子元件的时候找到了若干古董的CPU 其中有一个X3 440 是原来同学主板烧了之后给我的&#xff0c;我从网上配了AM2 昂达主板&#xff0c;然后又买了AMD兼容内存&#xff0c;组成了win7 64位电脑&#xff0c;用起来非常不错&#xff0c;我把硬件配置和升级过程说明下&#x…

C++对象模型

思考&#xff1a;对于实现平面一个点的参数化。C的class封装看起来比C的struct更加的复杂&#xff0c;是否意味着产生更多的开销呢&#xff1f; 实际上并没有&#xff0c;类的封装不会产生额外的开销&#xff0c;其实&#xff0c;C中在布局以及存取上的额外开销是virtual引起的…