14. golang之 JSON基本介绍

1. 概述

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。key-val

JSON是在2001年开始推广使用的数据格式,目前已经称为主流的数据格式

JSON易于机器解析和生成,并有效地提升网络传输效率,通常程序在网络传输时会先将数据(结构体、map等)序列化成JSON字符串,到接收方得到JSON字符串时,再反序列化恢复成原来的数据类型(结构体、map等)。这种方式已然成为各个语言的标准。

2. 应用场景(示意图)

 

3. JSON数据格式说明

 4. JSON数据在线解析

https://www.json.cn/ 网站可以验证一个json格式的数据是否正确。尤其在我们编写比较复杂的格式数据时,很有用。

5. JSON的序列化

 1)介绍

JSON序列化是指,将有key-value结构的数据类型(比如结构体、map、切片)序列化成JSON字符串的操作。

2)应用案例

这里我们介绍一下结构体、map和切片的序列化,其它数据类型的序列化类似。

代码演示:

package main
import (
	"fmt"
	"encoding/json"
)

// 定义一个结构体
type Monster struct {
	Name string
	Age int
	Birthday string
	Sal float64
	Skill string
}
// 将struct序列化
func testStruct () {
	// 演示
	monster := Monster{
		Name: "牛魔王",
		Age: 500,
		Birthday: "2011-11-11",
		Sal: 8000.0,
		Skill: "牛魔拳",
	}
	// 将monster序列化
	data, err := json.Marshal(&monster)
	if err != nil {
		fmt.Printf("序列化错误,err=%v\n",err)
	}
	// 输出序列化后的结果
	fmt.Printf("monster 序列化后的结果=%v\n",string(data))
}
// 将map序列化
func testMap() {
	// 定义一个map
	var a map[string]interface{}
    // 使用map,需要make
	a = make(map[string]interface{})
	a["name"] = "红孩儿"
	a["age"] = 30
	a["address"] = "洪崖洞"
	// 将a这个map进行序列化
	data, err := json.Marshal(a)
	if err != nil {
		fmt.Printf("序列化错误,err=%v\n",err)
	}
	fmt.Printf("map 序列化后的结果=%v\n",string(data))
}
// 演示对切片的序列化,我们这个切片[]map[string]interface{}
func testSlice() {
	var slice []map[string]interface{}
	var m1 map[string]interface{}
	// 使用map前,需要先make
	m1 = make(map[string]interface{})
	m1["name"] = "jack"
	m1["age"] = 100
	m1["address"] = "北京天安门"
	slice = append(slice,m1)

	var m2 map[string]interface{}
	// 使用map前,需要先make
	m2 = make(map[string]interface{})
	m2["name"] = "tom"
	m2["age"] = 20
	m2["address"] = [2]string{"墨西哥","夏威夷"}
	slice = append(slice, m2)
	// 将切片进行序列化
	data, err := json.Marshal(slice)
	if err != nil {
		fmt.Println("切片序列化错误,err=",err)
	}
	fmt.Printf("slice 序列化后=%v",string(data))
}
// 对基本数据类型序列化,对基本数据类型进行序列化意义不大
func testFloat64() {
	var num1 float64 = 23456.789
	// 对num1进行序列化
	data, err := json.Marshal(num1)
	if err != nil {
		fmt.Println("float64 序列化错误, err=",err)
	}
	// 输出序列化后的结果
	fmt.Println("float64 序列化后=%v\n",string(data))
}
func main() {
	testStruct()
	testMap()
	testSlice()
	testFloat64()
}

注意事项:

对于结构体的序列化,如果我们希望序列化后的key的名字,由我们自己重新指定,那么可以给struct指定一个tag标签

序列化后:

 6. JSON的反序列化

1)基本介绍

JSON反序列化是指,将JSON字符串反序列化成对应的数据类型(比如结构体、map、切片)的操作

2)应用案例

这里我们介绍一下将JSON字符串反序列化成结构体、map和切片

代码演示:

package main
import (
	"fmt"
	"encoding/json"
)
// 定义一个结构体
type Monster struct {
	Name string
	Age int
	Birthday string
	Sal float64
	Skill string
}

// 演示将JSON字符串,反序列化成struct
func unmarshalStruct() {
	// 说明 str在项目开发中,是通过网络传输获取到...  或是读取文件获取到
	str := "{\"Name\":\"孙悟空\",\"Age\": 500,\"Birthday\":\"2021-08-18\",\"Sal\":8000,\"Skill\":\"三昧真火\"}"

	// 定义一个Monster实例
	var monster Monster
	err := json.Unmarshal([]byte(str),&monster)
	if err != nil {
		fmt.Printf("unmarsha err=%v",err)
	}
	fmt.Printf("反序列化后  monster=%v monster.Name=%v\n",monster,monster.Name)
}
// 演示将JSON字符串,反序列化成map
func unmarshalMap() {
	str := "{\"address\":\"北京天安门\",\"age\":30,\"name\":\"奥特曼\"}"
	// 定义一个map
	var a map[string]interface{}
	// 反序列化
	// 注意:反序列化 map,不需要make,因为make操作被封装到Unmarshal函数
	err := json.Unmarshal([]byte(str),&a)
	if err != nil {
		fmt.Println("map 反序列化失败, err=",err)
	}
	fmt.Printf("反序列化后 a=%v\n",a)
}
// 演示将JSON字符串,反序列化成切片
func unmarshalSlice() {
	str := "[{\"address\":\"北京天安门\",\"age\":30,\"name\":\"李白\"},{\"address\":[\"南昌\",\"马六甲海峡\"],\"age\":30,\"name\":\"李白\"}]"
	// 定义一个slice
	var slice []map[string]interface{}
	// 反序列化,不需要make,因为make操作被封装到了Unmarshal函数
	err := json.Unmarshal([]byte(str), &slice)
	if err != nil {
		fmt.Println("slice 反序列化失败, err=",err)
	}
	fmt.Println("反序列化后=",slice)
}
func main() {
	unmarshalStruct()
	unmarshalMap()
	unmarshalSlice()
}

对上面代码的小结说明:

1)在反序列化一个JSON字符串时,要确保反序列化后的数据类型和原来序列化前的数据类型一致。

2)如果JSON字符串是通过程序获取到的,则不需要再对"进行转义处理。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值