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
结构示例:
{"key1": "value1","key2": 123,"key3": true, "key4": null, "key5": { "nestedKey1": "nestedValue1" }, "key6": ["element1", "element2", "element3"]}
反序列化后:
{"key1": "value1","key2": 123,"key3": true,"key4": null,"key5": {"nestedKey1": "nestedValue1"},"key6": ["element1","element2","element3"]
}
2.JSON数组
一个JSON数组是一个有序的值集合,它以左方括号 [
开始,以右方括号 ]
结束。数组中的元素可以是字符串、数字、布尔值、null、另一个JSON对象或数组,元素之间用逗号 ,
分隔
结构示例
[ "value1",123, true,null, {"key1": "value1" },["nestedElement1", "nestedElement2"]]
反序列化后
["value1",123,true,null,{"key1": "value1"},["nestedElement1","nestedElement2"]
]
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"}]}
反序列化后
{"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编码。
- 数据以键值对的形式出现。
- 键值对之间用逗号分隔。
- 对象由花括号
{}
包围,键值对由逗号,
分隔。 - 数组由方括号
[]
包围,元素之间由逗号,
分隔。 - 字符串必须用双引号
"
包围,特殊字符需要转义。 - 数字可以是整数或浮点数,但不能有前导零。
- 布尔值可以是
true
或false
。 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
将包含错误信息。
例子
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))
}
输出结果
{"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
将包含错误信息。
示例:
package mainimport ("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))
}
结果:
{"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
将包含错误信息。
示例
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 Personerr := 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)
}
输出结果
Name: 李四, Age: 25, Email: lisi@example.com
这样,你就完成了Go语言中的序列化和反序列化操作。这些操作在处理网络请求、文件存储和数据传输时非常有用。