Go对Json的支持[encoding/json]

news/2025/2/20 2:45:21/

数据类型中转json的函数

基本数据转json

Marshal使用以下与类型相关的默认编码:
布尔值编码为JSON布尔值。
浮点数、整数和数字值编码为JSON数字。
字符串值编码为JSON字符串,强制为有效的UTF-8;
用Unicode替换符文替换无效字节。
这样JSON就可以安全地嵌入到HTML

map转JSON


type user struct {Username string `json:"name"`Userid   string `json:"id"`Age      int    `json:"age"`
}func main() {jsonS()
}func jsonS() {//Go的标准包encoding/json对JSON的支持//JSON编码即将Go数据类型转换为JSON字符串m := make(map[string]interface{})m["name"] = "小花"m["age"] = 18u1 := user{Username: "小红",Userid:   "1024",Age:      10,}marshal, err := json.Marshal(m)i, _ := json.Marshal(u1)fmt.Println(i)fmt.Println(string(i))if err != nil {fmt.Println(err.Error())return}fmt.Println(string(marshal))
}

运行结果:
在这里插入图片描述

结构体转json

注意:如果结构体中的字段以小写字母开头,那么结构体在抓换 json时不会解析该字段:

如果结构体转json时定义的结构体没有指定转换json时的字段别名,那么结构体转json后会按照结构体字段名显示
例如:


type DogW struct {Name  stringAge   intcolor string
}type CatC struct {name  stringage   intcolor string
}type HenH struct {Name  string `json:"name"`Age   int    `json:"age"`Color string `json:"color"`
}func main() {d := DogW{Name:  "汪汪",Age:   2,color: "黄",}c := CatC{name:  "喵喵",age:   3,color: "狸花",}h := HenH{Name:  "咯咯哒",Age:   1,Color: "黄红",}indent, err := json.MarshalIndent(d, "", "")if err != nil {fmt.Println("转换失败")return}fmt.Println("Dog结构体转json--", string(indent))marshalIndent, err := json.MarshalIndent(c, "", " ")fmt.Println("Cat结构体转json--", string(marshalIndent))i, err := json.MarshalIndent(h, "", "")fmt.Println("Hen结构体转json--", string(i))}

在这里插入图片描述

将json输出格式化,以便于阅读

	u1 := user{Username: "小红",Userid:   "1024",Age:      10,}
//将json输出 格式化
// MarshalIndent类似于Marshal,但使用缩进来格式化输出。//输出中的每个JSON元素将在以prefix开头的新行开始//根据缩进嵌套,后跟一个或多个缩进副本。indent, err := json.MarshalIndent(u1, "", " ")fmt.Println(string(indent))

在这里插入图片描述

结构体匿名字段转Json

type DogW struct {DName  stringDAge   intDColor stringCatC   //匿名字段
}type CatC struct {Name  stringAge   intColor string
}func main() {d := DogW{DName:  "汪汪",DAge:   2,DColor: "黄",CatC: CatC{Name:  "喵喵",Age:   3,Color: "狸花",},}indent, err := json.MarshalIndent(d, "", "")if err != nil {fmt.Println("转换失败")return}fmt.Println("Dog结构体转json--", string(indent))}

在这里插入图片描述
注意:json包在解析匿名字段时,会将匿名字段的字段当成该结构体的字段处理

另外,如果嵌套的匿名字段的属性跟外部结构体的字段名一致,那么在转json后 只会显示外部的字段比如下面的代码:

type DogW struct {Name  stringAge   intColor stringCatC  //匿名字段
}type CatC struct {Name  stringAge   intColor string
}func main() {d := DogW{Name:  "汪汪",Age:   2,Color: "黄",CatC: CatC{Name:  "喵喵",Age:   3,Color: "狸花",},}indent, err := json.MarshalIndent(d, "", "")if err != nil {fmt.Println("转换失败")return}fmt.Println("Dog结构体转json--", string(indent))

在这里插入图片描述
这里就有许多情况—下面的情况就很好玩

type DogW struct {Name  stringAge   intcolor stringCatC  //匿名字段
}type CatC struct {Name  stringAge   intColor string
}func main() {d := DogW{Name:  "汪汪",Age:   2,color: "黄",CatC: CatC{Name:  "喵喵",Age:   3,Color: "狸花",},}
indent, err := json.MarshalIndent(d, "", "")if err != nil {fmt.Println("转换失败")return}fmt.Println("Dog结构体转json--", string(indent))

结果:
在这里插入图片描述

Marshal()函数源码

func Marshal(v any) ([]byte, error) {e := newEncodeState()defer encodeStatePool.Put(e)err := e.marshal(v, encOpts{escapeHTML: true})if err != nil {return nil, err}buf := append([]byte(nil), e.Bytes()...)return buf, nil
}

Marshal()函数只有在转换成功的时候才会返回数据,在转换的过程中需要注意如下几点。• JSON对象只支持string作为key,所以要编码一个map,必须是map[string]T这种类型(T是Go语言中的任意类型)。• channel、complex和function是不能被编码成JSON的。• 指针在编码的时候会输出指针指向的内容,而空指针会输出null。

json转Go中数据类型

//结构体
type CatC struct {Name  string `json:"name"`Age   int    `json:"age"`Color string `json:"color"`
}//json解析
//JSON解析就是将JSON转换为Go数据类型。func UNJSON() {d := DogW{Name:  "dog",Age:   2,color: "黄",CatC: CatC{Name:  "喵喵",Age:   3,Color: "狸花",},}//转换成jsonindent, err := json.MarshalIndent(d, "", " ")if err != nil {return}fmt.Println(string(indent))var dog DogW//json转go类型err = json.Unmarshal(indent, &dog)fmt.Println(dog)data := `[{"level":"debug","Msg":"File:\"test.txt\"NOT FOUND"},` + `{"Level":"","msg":"Logic error"}]`Catc := `{"Name":"狸花猫","Age":2,"Color":"梨花"}`Catd := `{"name":"狸花猫","age":2,"color":"梨花"}`var mapM []map[string]stringjson.Unmarshal([]byte(data), &mapM)var catc CatCvar catd CatCjson.Unmarshal([]byte(Catc), &catc)json.Unmarshal([]byte(Catd), &catd)fmt.Println(mapM)fmt.Println(catc)fmt.Println(catd)
}func main() {UNJSON()
}

注意json.Unmarshal([]byte(data), &mapM)中第二个参数要取址才会将解析出来的数据赋值给 对象mapM

JSON可以转换成结构体。同编码一样,json包是通过反射机制来实现解码的,因此结构体必须导出所转换的字段,不导出的字段不会被json包解析。另外解析时不区分大小写

json转结构体时也是支持json标签的:
结果如下:

{"Name": "dog","Age": 2,"name": "喵喵","age": 3,"color": "狸花"
}
{dog 2  {喵喵 3 狸花}}                                                     
[map[Msg:File:"test.txt"NOT FOUND level:debug] map[Level: msg:Logic error]]
{狸花猫 2 梨花}                                                            
{狸花猫 2 梨花}                                                            

如果在换转换时有匿名字段—>>

在解码JSON时,如果找不到字段,则查找字段的字段

比如下面的例子:

type CatCC struct {Name  string `json:"name"`Age   int    `json:"age"`Color string `json:"color"`
}
type DogWW struct {DName  stringDAge   intDcolor stringCatCC  //匿名字段
}func main() {//UNJSON()TestUnjson()
}func TestJson() {Dogw := `{"DName":"dogdog","DAge":22,"Dcolor":"Black","CatCC":{"Name":"喵miaomiao喵","Age":3,"Color":"狸花"}}`Dogww := `{"Name":"dogdog","Age":22,"color":"Red","CatCC":{"Name":"喵miaomiao喵","Age":3,"Color":"狸花"}}`var dog *DogWWvar dogw *DogWWjson.Unmarshal([]byte(Dogw), dog)json.Unmarshal([]byte(Dogww), dogw)fmt.Println(&dog)fmt.Println(&dogw)
}

运行结果:
在这里插入图片描述

结构体没有字段时,会使用结构体字段对应的类型默认值

这也体现了 结构体中嵌套了匿名结构体----继承

如果结构体属性中没有值,那么我们可以通过加入 json 字段来将空的值给忽略:

type User struct {Name  string   `json:"name"`Email string   `json:"email"` //加上omitempty标签,表示输出会将空值忽略掉,此时暂不加,看结果Hobby []string `json:"hobby"`
}func omitemptyDemo1() {// 当 struct 中的字段没有值Email,Hobby 字段时us := User{Name: "Gavin",}b, err := json.Marshal(us)if err != nil {fmt.Printf("json.Marshal failed, err:%v\n", err)return}fmt.Printf("str:%s\n", b)
}

运行结果:

{"name":"Jack","email":"","hobby":null}
str:{"name":"Jack","email":"","hobby":null}

加入omitempty标签后:

type User struct {Name  string   `json:"name"`Email string   `json:"email,omitempty"` //加上omitempty标签,表示输出会将空值忽略掉Hobby []string `json:"hobby,omitempty"`
}
//运行结果  str:{"name":"Jack"}   

json转嵌套结构体

type Pig struct {PName string `json:"pname"`Age   int    `json:"age"`
}type Animals struct {Types stringGroup []Pig
}func main() {var r Animalss := `{"Types":"猪","Group":[{"pname":"大猪","age":3},{"pname":"小猪仔","age":1}]}`err := json.Unmarshal([]byte(s), &r)if err != nil {fmt.Print(err)}fmt.Println(r)
}
文章来源:https://blog.csdn.net/weixin_54061333/article/details/130897998
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ppmy.cn/news/95001.html

相关文章

Zrlog接口测试:使用 fetchone() 方法从表中获取一条数据记录

# 导入 PyMySQL 库 import pymysql # 创建数据库对象 db pymysql.connect(# 设置数据库主机的地址host "192.168.199.204",# 设置数据库的用户名user "root",# 设置数据库password "123456",# 设置数据库的名称database "zrlog",…

【redis】Stream、String 超详细介绍

文章目录 一、Stream1.1 写入数据XADD条目 ID 的格式 1.2 获取数据XRANGE 和 XREVRANGEXREAD 监听新条目非阻塞形式阻塞形式 1.3 消费者组XGROUP 创建消费者组XREADGROUP 通过消费者组消费XACK 确认消息消费者组示例 1.4 XPENDING 和 XCLAIM 认领 其他消费者 的待处理消息XPEND…

To_Heart—题解——「NOI国赛 Round9」划分

大概的话就是晚鸢生完的。 可能还有的问题是对形式化题意不敏感?不知道了。 题意 给定长度为 2n 的两个序列 A,B,要求构造一个长度为 2n 的序列 C, C i C_i Ci​ A i A_i Ai​ 或 B i B_i Bi​ 。要求 C 单调不减。求 C 的方案数。 题…

数值计算 - 习题复习

1⃣️求矩阵的计算量 2⃣️求相对误差限 3⃣️根据最大误差求绝对误差限和相对误差限 ⚠️为什么使用微分? 绝对误差通过微分近似来计算基于这样的理念:如果我们在某个点附近考虑一个函数,那么该函数在该点附近的行为可以通过该点的切线来近似…

(八)K8S数据持久化存储

1.Volume讲解 概述: Volume是用于存储容器数据的抽象概念,它可以被挂载到一个或多个Pod中的一个或多个容器中。Volume提供了一种持久性的存储方式,使得容器中的数据可以在容器重启、重新调度或迁移时得以保留。 Kubernetes提供了多种类型的…

P1249 乘积最大

最大乘积 题目描述 一个正整数一般可以分为几个互不相同的自然数的和,如 3 1 2 312 312, 4 1 3 413 413, 5 = 1 4 2 3 5=1423 5=1423, 6 1 5 = 2 4 615=24 …

Altium Designer 相同电路多组复制布线

在进行设计开发的时候,总会遇到相同的电路,或者模块,这些电路可以使用相同的布局和走线。我们可以画好其中一部分,然后直接复制,就可以提高效率。下面记录我自己的实际操作过程,有一些地方遇到了问题&#…

首发Yolov8涨点神器:华为诺亚2023极简的神经网络模型 VanillaNet---VanillaBlock助力检测,实现暴力涨点

强烈推荐:博主多个数据集亲测有效,实现暴力涨点,可快速迁移到论文创新性十足,刚新鲜出炉的论文,华为诺亚共同提出!!! 1.VanillaNet 论文:https://arxiv.org/pdf/2305.12972.pdf 来自华为诺亚、悉尼大学的研究者们提出了一种极简的神经网络模型 VanillaNet,以极简主义…