结构体和 Json 相互转换(序列化反序列化)

关于 JSON 数据

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也
易于机器解析和生成。RESTfull Api 接口中返回的数据都是 json 数据。

Json 的基本格式如下:

复制代码
{
"a": "Hello",
"b": "World"
}

稍微复杂点的 JSON

结构体与 JSON 序列化

注意一个点:结构体内的私有属性不能被json包访问,如果结构体内部的属性都要就行转换,需要全部为公有属性(开头字符大写)
比如我们 Golang 要给 App 或者小程序提供 Api 接口数据,这个时候就需要涉及到结构体和
Json 之间的相互转换。
Golang JSON 序列化 是指把结构体数据转化成 JSON 格式的字符串;
(结构体 ----> JSON格式字符串)
Golang JSON 的反序列化 是指把 JSON 数据转化成 Golang 中的结构体对象。

(JSON格式字符串 ----> 结构体)

Golang 中 的 序 列 化 和 反 序 列 化 主 要 通 过**"encoding/json"** 包 中 的 j**son.Marshal()json.Unmarshal()**方法实现;

结构体对象转化成 Json 字符串

Go 复制代码
package main

import (
	"encoding/json"
	"fmt"
)



type Person struct{
	Name	string
	Gender	string
	Age 	int
}

func main() {

	var p1 = Person{
		Name: "奥特曼",
		Gender: "男",
		Age: 17,
	}
	fmt.Printf("%#v\n",p1)
		


	jsonByte,_ := json.Marshal(p1)
	jsonStr := string(jsonByte)
	fmt.Printf("%#v", jsonStr)

}

错误案例如下:

Go 复制代码
package main

import (
	"encoding/json"
	"fmt"
)



type Person struct{
	Name	string
	Gender	string
	age 	int
}

func main() {

	var p1 = Person{
		Name: "奥特曼",
		Gender: "男",
		age: 17,
	}
	fmt.Printf("%#v\n",p1)
		


	jsonByte,_ := json.Marshal(p1)
	jsonStr := string(jsonByte)
	fmt.Printf("%#v", jsonStr)

}

Json 字符串转换成结构体对象

返回一个err;

如果err为空,转换成功;

err非空,转换失败

Go 复制代码
package main

import (
	"encoding/json"
	"fmt"
)


type Person struct{
	Name	string
	Gender	string
	age 	int
}

func main() {
	var str = `{"Name":"奥特曼","Gender":"男","Age":17}`
	var p2 Person
	err := json.Unmarshal([]byte(str), &p2)

	if err != nil {  
		fmt.Println(err)
	}
	fmt.Printf("%#v\n", p2)
	fmt.Println(p2.Name)

}

结构体标签 Tag

Tag 是结构体的元信息,可以在运行的时候通过反射的机制读取出来。
Tag 在结构体字段的后方定义,由一对反引号包裹起来,具体的格式如下:
`key1:"value1" key2:"value2"`
结构体 tag 由一个或多个键值对组成。键与值使用冒号分隔,值用双引号括起来。
同一个结构体字段可以设置多个键值对 tag,不同的键值对之间使用空格分隔。
**注意事项:**为结构体编写 Tag 时,必须严格遵守键值对的规则。
结构体标签的解析代码的容错能力很差,一旦格式写错,编译和运行时都不会提示任何错误,通过反射也无法正确取值。
例如不要在 key 和 value 之间添加空格。

通过指定 tag 实现 json 序列化该字段时的 key

嵌套结构体和 JSON 序列化反序列化

Go 复制代码
package main

import (
	"encoding/json"
	"fmt"
)
type Person struct{
	Name	string `json:"name"`
	Gender	string `json:"gender"`
	Age 	int		`json:"age"`	
}

type Group struct{
	Intrasting string
	Person []Person
}
func main() {
	h := Group{
		Intrasting: "绘画",
		Person: make([]Person, 0),
	}
	for i := 17; i < 20; i++ {
		p := Person{
		Name :fmt.Sprintf("编号%v", i),  //字符串类型
		Gender:"男",
		Age : i+1,
		}
		h.Person = append(h.Person, p) //将P里的东西,添加到实例化的h后的切片内
	}
	// fmt.Println(c)
	strByte, err := json.Marshal(h)
	if err != nil {
		fmt.Println(err)
	} else {
		strJson := string(strByte)
		fmt.Println(strJson)
	}
}

逆序退回

Go 复制代码
package main

import (
	"encoding/json"
	"fmt"
)


type Person struct{
	Name	string `json:"name"`
	Gender	string `json:"gender"`
	Age 	int		`json:"age"`	
}

type Group struct{
	Intrasting string
	Person []Person
}

func main() {

	jsonStr := `{"Intrasting":"绘画","Person":[{"name":"编号17","gender":"男","age":18},{"name":"编号18","gender":"男","age":19},{"name":"编号19","gender":"男","age":20}]}`

	var h = &Group{}
	err := json.Unmarshal([]byte(jsonStr), h)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Printf("%#v\n", h)
		fmt.Printf("%v", h.Intrasting)
	}
}
相关推荐
花酒锄作田11 天前
Gin 框架中的规范响应格式设计与实现
golang·gin
qwfys20011 天前
How to install golang 1.26.0 to Ubuntu 24.04
ubuntu·golang·install
codeejun11 天前
每日一Go-25、Go语言进阶:深入并发模式1
开发语言·后端·golang
石牌桥网管11 天前
Go 泛型(Generics)
服务器·开发语言·golang
上海合宙LuatOS11 天前
LuatOS核心库API——【json 】json 生成和解析库
java·前端·网络·单片机·嵌入式硬件·物联网·json
敲代码的柯基11 天前
一篇文章理解tsconfig.json和vue.config.js
javascript·vue.js·json
小二·11 天前
Go 语言系统编程与云原生开发实战(第21篇)
开发语言·云原生·golang
小二·11 天前
Go 语言系统编程与云原生开发实战(第20篇)
开发语言·云原生·golang
女王大人万岁11 天前
Golang实战Eclipse Paho MQTT库:MQTT通信全解析
服务器·开发语言·后端·golang
codeejun11 天前
每日一Go-24、Go语言实战-综合项目:规划与搭建
开发语言·后端·golang