golang JSON序列化

JSON

JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。

json历史

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nsDku8I3-1722343372360)(https://i-blog.csdnimg.cn/direct/46affa558eeb4022b1508f014c7a6e03.png#pic_center)]

JSON建构于两种结构

  • "键/值"对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)
  • 值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)

1.JSON对象

一个JSON对象是一个无序的键/值对集合,它以左花括号 { 开始,以右花括号 } 结束。每个键值对包含一个键和一个值,键和值之间用冒号 : 分隔,键值对之间用逗号 , 分隔。键必须是字符串,而值可以是字符串、数字、另一个JSON对象、数组、布尔值或 null

结构示例:

json 复制代码
{"key1": "value1","key2": 123,"key3": true, "key4": null, "key5": { "nestedKey1": "nestedValue1"  }, "key6": ["element1", "element2", "element3"]}

反序列化后:

json 复制代码
{
    "key1": "value1",
    "key2": 123,
    "key3": true,
    "key4": null,
    "key5": {
        "nestedKey1": "nestedValue1"
    },
    "key6": [
        "element1",
        "element2",
        "element3"
    ]
}

2.JSON数组

一个JSON数组是一个有序的值集合,它以左方括号 [ 开始,以右方括号 ] 结束。数组中的元素可以是字符串、数字、布尔值、null、另一个JSON对象或数组,元素之间用逗号 , 分隔

结构示例

json 复制代码
[ "value1",123, true,null, {"key1": "value1" },["nestedElement1", "nestedElement2"]]

反序列化后

json 复制代码
[
    "value1",
    123,
    true,
    null,
    {
        "key1": "value1"
    },
    [
        "nestedElement1",
        "nestedElement2"
    ]
]

JSON的嵌套结构

JSON对象和数组可以相互嵌套,形成更复杂的数据结构

示例

json 复制代码
{"name": "张三","age": 30,"isStudent": false,"address": {"street": "科技路","city": "北京","postalCode": "100000"},"phoneNumbers": [{"type": "home","number": "123-456-7890"},{"type": "work","number": "987-654-3210"}]}

反序列化后

json 复制代码
{
    "name": "张三",
    "age": 30,
    "isStudent": false,
    "address": {
        "street": "科技路",
        "city": "北京",
        "postalCode": "100000"
    },
    "phoneNumbers": [
        {
            "type": "home",
            "number": "123-456-7890"
        },
        {
            "type": "work",
            "number": "987-654-3210"
        }
    ]
}

JSON的语法规则

  • 使用UTF-8编码。
  • 数据以键值对的形式出现。
  • 键值对之间用逗号分隔。
  • 对象由花括号 {} 包围,键值对由逗号 , 分隔。
  • 数组由方括号 [] 包围,元素之间由逗号 , 分隔。
  • 字符串必须用双引号 " 包围,特殊字符需要转义。
  • 数字可以是整数或浮点数,但不能有前导零。
  • 布尔值可以是 truefalse
  • null 表示空值。
  • 对象和数组可以嵌套使用。
  • 没有注释。
  • 键必须是双引号包围的字符串。
  • 值可以是字符串、数字、布尔值、null、对象或数组。

Go语言json序列化

在Go语言中,序列化(Serialization)是将内存中的数据结构转换为可存储或传输的格式,如JSON、XML、Protocol Buffers等。反序列化(Deserialization)则是将存储或传输的格式转换回内存中的数据结构。Go语言标准库中的encoding/json包提供了JSON序列化的功能。

1.func Marshal

func Marshal(v interface{}) ([]byte, error)

Marshal函数返回v的json编码。

Marshal函数会递归的处理值。如果一个值实现了Marshaler接口切非nil指针,会调用其MarshalJSON方法来生成json编码。nil指针异常并不是严格必需的,但会模拟与UnmarshalJSON的行为类似的必需的异常。

  • v:这是一个空接口,它代表了你要序列化的Go语言数据结构。使用空接口作为形参使得该函数可接受任何类型的值
  • []byte:这是一个字节切片,它包含了序列化后的JSON格式的数据。这是Marshal函数的主要输出,表示序列化后的数据。
  • error:这是一个可能的错误值。如果序列化过程成功,error将被设置为nil;如果序列化过程中发生错误,error将包含错误信息。

例子

go 复制代码
package main
import (
	"encoding/json"
	"fmt"
)
type Person struct {
	Name  string `json:"name"`
	Age   int    `json:"age"`
	Email string `json:"email"`
}
func main() {
	person := Person{
		Name:  "张三",
		Age:   30,
		Email: "zhangsan@example.com",
	}
	// 将结构体序列化为JSON格式的字节切片
	data, err := json.Marshal(person)
	if err != nil {
		fmt.Println("序列化失败:", err)
		return
	}
	// 将字节切片转换为字符串以打印
	fmt.Println(string(data))
}

输出结果

go 复制代码
{"name":"张三","age":30,"email":"zhangsan@example.com"}

2.func MarshalIndent

func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)

MarshalIndent类似Marshal但会使用缩进将输出格式化。

  • v:这是一个空接口,它代表了你要序列化的Go语言数据结构。使用空接口作为形参使得该函数可接受任何类型的值
  • prefix:一个字符串,它将作为每个JSON键的前缀。默认值为空字符串,表示不添加前缀
  • indent:一个字符串,它将作为缩进字符串。默认值为空字符串,表示不添加缩进
  • []byte:这是一个字节切片,它包含了序列化后的JSON格式的数据。这是Marshal函数的主要输出,表示序列化后的数据。
  • error:这是一个可能的错误值。如果序列化过程成功,error将被设置为nil;如果序列化过程中发生错误,error将包含错误信息。

示例:

go 复制代码
package main

import (
    "encoding/json"
    "fmt"
)

type Person struct {
    Name  string `json:"name"`
    Age   int    `json:"age"`
    Email string `json:"email"`
}

func main() {
    person := Person{
        Name:  "张三",
        Age:   30,
        Email: "zhangsan@example.com",
    }

    // 将结构体序列化为JSON格式的字节切片,并添加缩进
    data, err := json.MarshalIndent(person, "", "    ")
    if err != nil {
        fmt.Println("序列化失败:", err)
        return
    }

    // 将字节切片转换为字符串以打印
    fmt.Println(string(data))
}

结果:

go 复制代码
{
    "name": "张三",
    "age": 30,
    "email": "zhangsan@example.com"
}

Go语言反序列化

Go语言中的反序列化是将JSON格式的字符串转换回Go语言的数据结构。使用encoding/json包来完成这个过程

函数:

func Unmarshal

func Unmarshal(data []byte, v interface{}) error

Unmarshal函数解析json编码的数据并将结果存入v指向的值。

  • data:这是一个字节切片,它包含了JSON格式的数据。这是Unmarshal函数的输入,表示要反序列化的数据。
  • v:这是一个接口值,它代表了你要反序列化的Go语言数据结构。使用空接口作为形参使得该函数可接受任何类型的值
  • 返回值:一个可能的错误值。如果反序列化过程成功,error将被设置为nil;如果反序列化过程中发生错误,error将包含错误信息。

示例

go 复制代码
package main
import (
	"encoding/json"
	"fmt"
)
type Person struct {
	Name  string `json:"name"`
	Age   int    `json:"age"`
	Email string `json:"email"`
}
func main() {
	// 假设我们有一个JSON格式的字符串
	jsonString := `{"name":"李四","age":25,"email":"lisi@example.com"}`
	// 将JSON字符串反序列化为Go语言中的结构体
	var person Person
	err := json.Unmarshal([]byte(jsonString), &person)
	if err != nil {
		fmt.Println("反序列化失败:", err)
		return
	}
	// 输出反序列化后的结构体
	fmt.Printf("Name: %s, Age: %d, Email: %s\n", person.Name, person.Age, person.Email)
}

输出结果

go 复制代码
Name: 李四, Age: 25, Email: lisi@example.com

这样,你就完成了Go语言中的序列化和反序列化操作。这些操作在处理网络请求、文件存储和数据传输时非常有用。

相关推荐
爱吃喵的鲤鱼5 分钟前
linux进程的状态之环境变量
linux·运维·服务器·开发语言·c++
DARLING Zero two♡32 分钟前
关于我、重生到500年前凭借C语言改变世界科技vlog.16——万字详解指针概念及技巧
c语言·开发语言·科技
Gu Gu Study34 分钟前
【用Java学习数据结构系列】泛型上界与通配符上界
java·开发语言
芊寻(嵌入式)1 小时前
C转C++学习笔记--基础知识摘录总结
开发语言·c++·笔记·学习
AskHarries1 小时前
Java字节码增强库ByteBuddy
java·后端
一颗松鼠1 小时前
JavaScript 闭包是什么?简单到看完就理解!
开发语言·前端·javascript·ecmascript
有梦想的咸鱼_1 小时前
go实现并发安全hashtable 拉链法
开发语言·golang·哈希算法
海阔天空_20131 小时前
Python pyautogui库:自动化操作的强大工具
运维·开发语言·python·青少年编程·自动化
佳佳_1 小时前
Spring Boot 应用启动时打印配置类信息
spring boot·后端
天下皆白_唯我独黑1 小时前
php 使用qrcode制作二维码图片
开发语言·php