【go从零单排】JSON序列化和反序列化

🌈Don't worry , just coding!
内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。

📗概念

在 Go 语言中,处理 JSON 数据主要依赖于 encoding/json 包。这个包提供了编码(序列化)和解码(反序列化)JSON 数据的功能。

💻代码

Example

go 复制代码
package main

//导入了 encoding/json(用于处理 JSON 数据)、fmt(用于格式化输出)和 os(用于操作系统功能)包。
import (
	"encoding/json"
	"fmt"
	"os"
)

// 定义了两个结构体 response1 和 response2。
// response2 使用了结构体标签(tags),指定了 JSON 字段名,这样在序列化时可以控制字段名称
type response1 struct {
	Page   int//首字母必须大写才能导出字段
	Fruits []string
}

type response2 struct {
	Page   int      `json:"page"`
	Fruits []string `json:"fruits"`
}

func main() {
	//使用 json.Marshal 将其转换为 JSON 格式的字节切片,并转为字符串输出。
	bolB, _ := json.Marshal(true)
	fmt.Println(string(bolB)) // 输出: true

	intB, _ := json.Marshal(1)
	fmt.Println(string(intB)) // 输出: 1

	fltB, _ := json.Marshal(2.34)
	fmt.Println(string(fltB)) // 输出: 2.34

	strB, _ := json.Marshal("gopher")
	fmt.Println(string(strB)) // 输出: "gopher"

	slcD := []string{"apple", "peach", "pear"}
	slcB, _ := json.Marshal(slcD)
	fmt.Println(string(slcB)) // 输出: ["apple","peach","pear"]

	mapD := map[string]int{"apple": 5, "lettuce": 7}
	mapB, _ := json.Marshal(mapD)
	fmt.Println(string(mapB)) // 输出: {"apple":5,"lettuce":7}

	res1D := &response1{
		Page:   1,
		Fruits: []string{"apple", "peach", "pear"}}
	res1B, _ := json.Marshal(res1D)
	fmt.Println(string(res1B)) // 输出: {"Page":1,"Fruits":["apple","peach","pear"]}

	res2D := &response2{
		Page:   1,
		Fruits: []string{"apple", "peach", "pear"}}
	res2B, _ := json.Marshal(res2D)
	fmt.Println(string(res2B)) // 输出: {"page":1,"fruits":["apple","peach","pear"]}

	byt := []byte(`{"num":6.13,"strs":["a","b"]}`)

	var dat map[string]interface{}

	if err := json.Unmarshal(byt, &dat); err != nil {
		panic(err)
	}
	fmt.Println(dat) // 输出: map[num:6.13 strs:[a b]]

	num := dat["num"].(float64)//num是float的类型,这里需要手动转化
	fmt.Println(num)

	strs := dat["strs"].([]interface{})
	str1 := strs[0].(string)
	fmt.Println(str1)

	str := `{"page": 1, "fruits": ["apple", "peach"]}`
	res := response2{}
	//[]byte(str) 将 JSON 字符串 str 转换为字节切片,以便 Unmarshal 函数可以处理。
	//&res 是一个指向 res 的指针,表示解码后的数据将存储在 res 中。
	json.Unmarshal([]byte(str), &res)
	fmt.Println(res)           // 输出: {1 [apple peach]}
	fmt.Println(res.Fruits[0]) // 输出: apple
	//使用 json.NewEncoder 创建一个 JSON 编码器,将数据直接编码到标准输出流(os.Stdout)。
	enc := json.NewEncoder(os.Stdout)
	d := map[string]int{"apple": 5, "lettuce": 7}
	enc.Encode(d) // 输出: {"apple":5,"lettuce":7}
}

//输出
//true
//1
//2.34
//"gopher"
//["apple","peach","pear"]
//{"apple":5,"lettuce":7}
//{"Page":1,"Fruits":["apple","peach","pear"]}
//{"page":1,"fruits":["apple","peach","pear"]}
//map[num:6.13 strs:[a b]]
//6.13
//a
//{1 [apple peach]}
//apple
//{"apple":5,"lettuce":7}

序列化

将 Go 数据结构转换为 JSON 格式的字符串。

go 复制代码
package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    // 示例数据
    data := map[string]interface{}{
        "name": "Alice",
        "age":  30,
        "hobbies": []string{"reading", "traveling"},
    }

    // 编码为 JSON
    jsonData, err := json.Marshal(data)
    if err != nil {
        fmt.Println("Error encoding JSON:", err)
        return
    }
    fmt.Println(string(jsonData)) // 输出: {"age":30,"hobbies":["reading","traveling"],"name":"Alice"}
}

反序列化

将 JSON 格式的字符串转换为 Go 数据结构。

go 复制代码
package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    jsonStr := `{"name": "Alice", "age": 30, "hobbies": ["reading", "traveling"]}`

    var data map[string]interface{}

    // 解码 JSON
    err := json.Unmarshal([]byte(jsonStr), &data)
    if err != nil {
        fmt.Println("Error decoding JSON:", err)
        return
    }
    fmt.Println(data) // 输出: map[age:30 hobbies:[reading traveling] name:Alice]
}

切片序列化

Go 的切片可以直接映射到 JSON 数组。

go 复制代码
func main() {
    fruits := []string{"apple", "banana", "cherry"}
    
    jsonData, err := json.Marshal(fruits)
    if err != nil {
        fmt.Println("Error encoding JSON:", err)
        return
    }
    fmt.Println(string(jsonData)) // 输出: ["apple","banana","cherry"]
}

使用 JSON 标签

通过结构体标签自定义 JSON 字段名。

go 复制代码
type Person struct {
    Name    string   `json:"name"`
    Age     int      `json:"age"`
    Hobbies []string `json:"hobbies"`
}

序列化结构体

go 复制代码
package main

import (
	"encoding/json"
	"fmt"
)
//定义结构体
type Person struct {
	Name    string   `json:"name"`
	Age     int      `json:"age"`
	Hobbies []string `json:"hobbies"`
}

func main() {
	person := Person{
		Name:    "Alice",
		Age:     30,
		Hobbies: []string{"reading", "traveling"},
	}
	//序列化结构体
	jsonData, err := json.Marshal(person)
	if err != nil {
		fmt.Println("Error encoding JSON:", err)
		return
	}
	fmt.Println(string(jsonData)) // 输出: {"age":30,"hobbies":["reading","traveling"],"name":"Alice"}
}

反序列化结构体

go 复制代码
func main() {
    jsonStr := `{"name": "Alice", "age": 30, "hobbies": ["reading", "traveling"]}`
    
    var person Person
    //[]byte(jsonStr) 将一个字符串(jsonStr)转换为字节切片。这是因为 json.Unmarshal 需要一个字节切片作为输入参数,而不是字符串。
    err := json.Unmarshal([]byte(jsonStr), &person)
    if err != nil {
        fmt.Println("Error decoding JSON:", err)
        return
    }
    fmt.Println(person) // 输出: {Alice 30 [reading traveling]}
}
  • 在 Go 中,json.Unmarshal 函数用于将 JSON 格式的字节切片解码为 Go 数据结构。这里的 \[\]byte 是一个字节切片类型,表示 JSON 数据的原始字节序列。
  • 字节切片:\[\]byte 是 Go 中的一个基本数据类型,表示一个字节的动态数组。每个字节是一个 8 位的无符号整数,通常用于表示原始数据,如文本、二进制数据等。
  • JSON 字符串:在 JSON 数据的上下文中,JSON 字符串通常是以 UTF-8 编码的文本。要将 JSON 字符串转换为 Go 数据结构,首先需要将其转换为字节切片。

🔍理解

  • 序列化是把go的数据结构转为json格式,用json.Marshal(data)
  • 反序列化是把json格式转为go的数据格式,用json.Unmarshal

💡 Tips小知识点

错误处理

在编码和解码过程中,建议检查错误,以确保数据的正确性。

go 复制代码
if err != nil {
    fmt.Println("Error:", err)
}

JSON 编码到输出流

使用 json.Encoder 将 JSON 数据直接写入到输出流(如标准输出)。

go 复制代码
enc := json.NewEncoder(os.Stdout)
data := map[string]int{"apple": 5, "banana": 2}
enc.Encode(data) // 输出: {"apple":5,"banana":2}

💪无人扶我青云志,我自踏雪至山巅。

相关推荐
联犀13 小时前
联犀 Go SIMD 实战:视频转码从 16.5ms 到 5.46ms
开发语言·golang·音视频
程序员大阳1 天前
副队长JavaScript教程(66)-本地存储实战:待办事项网页的开发
javascript·json·实战·待办事项·本地存储·案例
紧跟先前的步伐1 天前
Go AI Agent 实战 28|Agent 的预算、超时与停止条件
开发语言·人工智能·后端·ai·golang
利威尔xu2 天前
2026-11-05-Go内存管理面试
面试·golang
视觉小萌新2 天前
AI Class 3 · Chapter 2-3:函数、异常、文件读写+JSON / JSONL 读写(小白版)
人工智能·python·json
翊众建站3 天前
用 JSON-LD 给企业官网做结构化数据:LocalBusiness 与 FAQPage 实践笔记
人工智能·搜索引擎·json
Zenova EdgeOS3 天前
Go 工业边缘错误处理实战:用 errors 构建可追溯错误链
开发语言·数据库·golang
JavaPub-rodert3 天前
从零搭建通用管理后台:ShiyuAdmin 的 Go、React 与 RBAC 实践
开发语言·react.js·golang
Patrick_Wilson3 天前
读懂一个 Go JSON 处理函数:从输入数据追踪结构体、校验与错误返回
go·json·编程语言
microrain3 天前
SagooIoT 的数据接入层只有四张表,却能接住三种外部数据
物联网·golang·数据建模·sagooiot