有点技巧的go语言JSON格式使用 | 青训营

619 阅读4分钟

在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 数据时提供更好的可读性。您可以根据自己的喜好设置前缀和缩进字符串,以满足不同的输出需求。