在Go语言的实训案例中,对于使用JSON格式的感觉非常抽象,经常无法很好地使用其标准库。编码/解码库encoding/json可以很方便地理解和记忆。
作为一个初学者,我希望得到大家的指点。视频中的实战案例提供了一种解析方式,即构造一个与JSON数据格式相对应的结构体,将JSON格式转化为该结构体的对象,然后通过结构体的方法对数据内容进行操作。
当然,在视频中还提供了相应的工具,用于将JSON数据转化为对应的Go语言结构体格式。这个工具非常实用,以下是相关链接:JSON转Golang Struct - 在线工具 - OKTools。JSON转
JSON转Golang Struct - 在线工具 - OKTools
一.首先对encoding/json库中常用的方法进行讲解:
1. json.Marshal()序列化:将数据结构序列化为JSON格式的字节切片。这个方法将数据转换为JSON格式的过程。它在程序中帮助我们处理和操作数据,将数据编码为符合标准的JSON格式,从而更方便地与其他系统或服务进行数据交互。
下面是一个示例,供参考:
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
// 创建 Person 对象
person := Person{
Name: "Alice",
Age: 30,
}
// 编码为 JSON
jsonData, err := json.Marshal(person)
if err != nil {
fmt.Println("JSON encoding failed:", err)
return
}
// 打印 JSON 数据
fmt.Println(string(jsonData))
// 解码 JSON
var decodedPerson Person
err = json.Unmarshal(jsonData, &decodedPerson)
if err != nil {
fmt.Println("JSON decoding failed:", err)
return
}
// 打印解码后的 Person 对象
fmt.Println(decodedPerson)
}
输出结果为
{"name":"Alice","age":30}
{Name:Alice Age:30}
这个示例展示了一个完整的流程。它包括将 Person 对象编码为 JSON 字节切片,并将其打印出来,然后再将 JSON 字节切片解码为 Person 对象,并将解码后的对象打印出来。
对于这种方法,它将 JSON 转换为结构体格式,并使用结构体的方法进行后续操作。
遍历
// 遍历切片,访问每个 Person 对象的字段
for _, p := range persons {
fmt.Println("Name:", p.Name)
fmt.Println("Age:", p.Age)
fmt.Println("---")
}
............................................................................................
Name: Alice
Age: 30
---
Name: Bob
Age: 25
---
Name: Charlie
Age: 35
---
访问与操作
访问与操作 // 访问和使用切片中的一个 Person 对象
person := persons[1] // 使用索引 1 获取第二个 Person 对象
fmt.Println("Name:", person.Name)
fmt.Println("Age:", person.Age)
..............................................................................................
Name: Bob
Age: 25
修改相应字段
修改相应字段
// 修改字段值
person.Name = "Bob"
person.Age = 25...........................................................................................
2.json.Unmarshal()
将 JSON 反序列化为数据结构::函数将 JSON 格式的字节切片反序列化为相应的 Go 数据结构。
可以通过这三钟方式使用json.Unmarshal()
对于 JSON 对象:如果您反序列化的是一个 JSON 对象,您可以使用 range 关键字迭代对象中的键值对。例如:var obj map[string]interface{}
err := json.Unmarshal(jsonData, &obj)
if err != nil {
fmt.Println("JSON unmarshaling failed:", err)
}
for key, value := range obj {
fmt.Printf("Key: %s, Value: %v\n", key, value)
}
obj 是一个 map[string]interface{} 类型,表示反序列化后的 JSON 对象。
使用 range 关键字,您可以迭代对象的键值对,并在循环中访问它们。
对于 JSON 数组:
var obj map[string]interface{}
err := json.Unmarshal(jsonData, &obj)
if err != nil {
fmt.Println("JSON unmarshaling failed:", err)
}
for key, value := range obj {
fmt.Printf("Key: %s, Value: %v\n", key, value)
}
obj 是一个 map[string]interface{} 类型,表示反序列化后的 JSON 对象。
使用 range 关键字,您可以迭代对象的键值对,并在循环中访问它们。
对于自定义的结构体:如果您反序列化的是一个自定义的结构体对象,您可以像遍历任何其他结构体一样,使用点 . 运算符来访问其字段。type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
var person Person
err := json.Unmarshal(jsonData, &person)
if err != nil {
fmt.Println("JSON unmarshaling failed:", err)
}
fmt.Println("Name:", person.Name)
fmt.Println("Age:", person.Age)
person 是一个自定义的 Person 结构体对象,表示反序列化后的 JSON 数据。
您可以直接访问该结构体的字段,获取它们的值。
3.json.Indent():
json.Indent() 函数用于格式化 JSON 数据,它会添加缩进和换行符,使其更易读。该函数的签名如下:
func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error
参数说明:
dst:一个*bytes.Buffer类型的指针,用于接收格式化后的 JSON 数据。src:一个[]byte类型的字节切片,包含要进行格式化的原始 JSON 数据。prefix:一个字符串,表示每行的前缀。通常用于指定初始缩进或空格填充。indent:一个字符串,表示每级缩进的字符串。可以使用空格、制表符等。
示例
import (
"encoding/json"
"bytes"
"fmt"
)
func main() {
jsonData := []byte(`{"name":"Alice","age":30}`)
var formattedData bytes.Buffer
err := json.Indent(&formattedData, jsonData, "", " ")
if err != nil {
fmt.Println("JSON formatting failed:", err)
}
fmt.Println(formattedData.String())
}
在上述示例中,我们将原始的 JSON 数据 jsonData 进行格式化,并将格式化后的数据写入 formattedData 缓冲区。"" 表示每行的前缀为空," " 表示每级缩进为两个空格。
输出结果:
{
"name": "Alice",
"age": 30
}
可以看到这个函数非常好用,原始的 JSON 数据被格式化后,每个字段都以适当的缩进进行了排列,并且每个字段之间有换行符分隔。json.Indent() 函数非常方便,可以为您在打印或展示 JSON 数据时提供更好的可读性。您可以根据自己的喜好设置前缀和缩进字符串,以满足不同的输出需求。