十一、结构体和 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" 包 中 的 json.Marshal() json.Unmarshal()方法实现;

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

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)

}

 错误案例如下:

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非空,转换失败

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 序列化反序列化 

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)
	}
}

 逆序退回

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)
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
结构序列序列是将结构数据转换为字节流,以便在网络传输或存储中使用,然后再将字节流还原为原始结构数据的过程。 在C++中,可以通过以下几种方式实现结构序列序列: 1. 使用二进制流进行序列序列:可以使用std::ofstream和std::ifstream类来将结构数据写入文件或从文件读取结构数据。例如: ```cpp struct MyStruct { int a; float b; char c; }; void serialize(const MyStruct& data, const std::string& filename) { std::ofstream file(filename, std::ios::binary); file.write(reinterpret_cast<const char*>(&data), sizeof(MyStruct)); file.close(); } void deserialize(MyStruct& data, const std::string& filename) { std::ifstream file(filename, std::ios::binary); file.read(reinterpret_cast<char*>(&data), sizeof(MyStruct)); file.close(); } ``` 2. 使用JSON进行序列序列:可以使用第三方库(如RapidJSON、nlohmann/json等)将结构数据转换JSON格式的字符串,然后再将JSON字符串转换结构数据。例如: ```cpp #include <iostream> #include <string> #include <nlohmann/json.hpp> struct MyStruct { int a; float b; char c; }; void serialize(const MyStruct& data, const std::string& filename) { nlohmann::json json_data; json_data["a"] = data.a; json_data["b"] = data.b; json_data["c"] = data.c; std::ofstream file(filename); file << json_data.dump(4); // 4为缩进级别 file.close(); } void deserialize(MyStruct& data, const std::string& filename) { std::ifstream file(filename); nlohmann::json json_data; file >> json_data; file.close(); data.a = json_data["a"]; data.b = json_data["b"]; data.c = json_data["c"]; } int main() { MyStruct original_data {42, 3.14f, 'A'}; serialize(original_data, "data.json"); MyStruct restored_data; deserialize(restored_data, "data.json"); std::cout << "Restored data: a = " << restored_data.a << ", b = " << restored_data.b << ", c = " << restored_data.c << std::endl; return 0; } ``` 以上是两种常见的结构序列序列的方式,具选择哪种方式取决于你的需求和场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵唯一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值