Salmon的全栈知识 Salmon的全栈知识
首页
  • JavaSE
  • JavaWeb
  • Spring生态
  • JUC
  • JVM
  • Netty
  • Java各版本特性
  • 23种设计模式
  • Maven
  • Java常用框架
  • Dubbo
  • OpenFeign
  • Nacos
  • Zookeeper
  • Sentinel
  • Seata
  • Gateway
  • Go基础
  • Gin
  • SQL数据库

    • MySQL
    • Oracle
  • NoSQL数据库

    • Redis
    • MongoDB
    • ElasticSearch
  • 消息中间件

    • RabbitMQ
    • RocketMQ
    • Kafka
    • ActiveMQ
    • MQTT
    • NATS
  • 网关中间件

    • Nginx
  • Linux
  • Docker
  • Git
  • K8s
  • Solidity
  • Java
  • 计算机网络
  • 操作系统
GitHub (opens new window)
首页
  • JavaSE
  • JavaWeb
  • Spring生态
  • JUC
  • JVM
  • Netty
  • Java各版本特性
  • 23种设计模式
  • Maven
  • Java常用框架
  • Dubbo
  • OpenFeign
  • Nacos
  • Zookeeper
  • Sentinel
  • Seata
  • Gateway
  • Go基础
  • Gin
  • SQL数据库

    • MySQL
    • Oracle
  • NoSQL数据库

    • Redis
    • MongoDB
    • ElasticSearch
  • 消息中间件

    • RabbitMQ
    • RocketMQ
    • Kafka
    • ActiveMQ
    • MQTT
    • NATS
  • 网关中间件

    • Nginx
  • Linux
  • Docker
  • Git
  • K8s
  • Solidity
  • Java
  • 计算机网络
  • 操作系统
GitHub (opens new window)
npm

(进入注册为作者充电)

  • Go语言介绍以及win环境搭建
  • Go语言 Mac电脑环境搭建、开发工具Vscode配置
  • Go语言 定义变量、 fmt包、Println、Printf、Go语言注释
  • Go变量 常量申明 变量命名规则
  • Go语言基本数据类型
  • GoLang中基本数据类型之间的转换
  • Golang中的运算符
  • Go语言中的流程控制
  • Golang中的数组
  • Golang中的切片
  • Golang map 详解
  • Golang函数详解
  • Golang time包以及日期函数
  • Golang中的指针
  • Golang中的结构体详解
  • Golang结构体和Json相互转换 序列化 反序列化
    • 一、关于 JSON 数据
    • 二、结构体与 JSON 序列化
      • 1、结构体对象转化成 Json 字符串
      • 2、Json 字符串转换成结构体对象
    • 三、结构体标签 Tag
    • 四、嵌套结构体和 JSON 序列化反序列化
    • 五、关于 Map、切片的序列化反序列化
  • Golang 中的 go mod 以及 Golang 包详解
  • Golang中的接口详解
  • Golang goroutine channel实现并发和并行
  • Golang 反射
  • Golang 文件 目录操作
  • 《Go基础》笔记
Salmon
2025-03-16
目录

Golang结构体和Json相互转换 序列化 反序列化

# 一、关于 JSON 数据

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。RESTfull Api 接口中返回的数据都是 json 数据。

Json 的基本格式如下:

{
  "a": "Hello",
  "b": "World"
}

稍微复杂点的 JSON

{
  "result": [
    {
      "_id": "59f6ef443ce1fb0fb02c7a43",
      "title": "笔记本电脑",
      "status": "1",
      "pic": "public\\upload\\UObZahqPYzFvx_C9CQjU8KiX.png",
      "url": "12"
    },
    {
      "_id": "5a012efb93ec4d199c18d1b4",
      "title": "第二个轮播图",
      "status": "1",
      "pic": "public\\upload\\f3OtH11ZaPX5AA4Ov95Q7DEM.png"
    },
    {
      "_id": "5a012f2433574208841e0820",
      "title": "第三个轮播图",
      "status": "1",
      "pic": "public\\upload\\s5ujmYBQVRcLuvBHvWFMJHzS.jpg"
    },
    {
      "_id": "5a688a0ca6dcba0ff4861a3d",
      "title": "教程",
      "status": "1",
      "pic": "public\\upload\\Zh8EP9HOasV28ynDSp8TaGwd.png"
    }
  ]
}

# 二、结构体与 JSON 序列化

比如我们 Golang 要给 App 或者小程序提供 Api 接口数据,这个时候就需要涉及到结构体和Json 之间的相互转换

Golang JSON 序列化是指把结构体数据转化成 JSON 格式的字符串,Golang JSON 的反序列化是指把 JSON 数据转化成 Golang 中的结构体对象

Golang 中 的 序 列 化 和 反 序 列 化 主 要 通 过"encoding/json" 包 中 的 json.Marshal() 和 json.Unmarshal()方法实现

# 1、结构体对象转化成 Json 字符串

package main

import (
    "encoding/json"
    "fmt"
)

type Student struct {
    ID     int
    Gender string
    name   string //私有属性不能被 json 包访问
    Sno    string
}

func main() {
    var s1 = Student{
       ID: 1, Gender: "男", name: "李四", Sno: "s0001"}
    fmt.Printf("%#v\n", s1)
    var s, _ = json.Marshal(s1)
    jsonStr := string(s)
    fmt.Println(jsonStr)
}

输出结果:

main.Student{ID:1, Gender:"男", name:"李四", Sno:"s0001"}
{"ID":1,"Gender":"男","Sno":"s0001"}

# 2、Json 字符串转换成结构体对象

package main

import (
    "encoding/json"
    "fmt"
)

type Student struct {
    ID     int
    Gender string
    Name   string
    Sno    string
}

func main() {
    // var jsonStr = "{\"ID\":1,\"Gender\":\"男\",\"Name\":\"李四\",\"Sno\":\"s0001\"}"
    var jsonStr = `{"ID":1,"Gender":"男","Name":"李四","Sno":"s0001"}` //定义一个 Monster 实例
    var student Student
    err := json.Unmarshal([]byte(jsonStr), &student)
    if err != nil {
       fmt.Printf("unmarshal err=%v\n", err)
    }
    fmt.Printf("反序列化后 student=%#v student.Name=%v \n", student, student.Name)
}

输出结果:

反序列化后 student=main.Student{ID:1, Gender:"男", Name:"李四", Sno:"s0001"} student.Name=李四

# 三、结构体标签 Tag

Tag 是结构体的元信息,可以在运行的时候通过反射的机制读取出来。 Tag 在结构体字段的后方定义,由一对反引号包裹起来,具体的格式如下:

key1:"value1" key2:"value2" 结构体 tag 由一个或多个键值对组成。键与值使用冒号分隔,值用双引号括起来。同一个结构体字段可以设置多个键值对 tag,不同的键值对之间使用空格分隔。

注意事项: 为结构体编写 Tag 时,必须严格遵守键值对的规则。结构体标签的解析代码的容错能力很差,一旦格式写错,编译和运行时都不会提示任何错误,通过反射也无法正确取值。例如不要在 key 和 value 之间添加空格。

package main

import (
    "encoding/json"
    "fmt"
)

type Student struct {
    ID     int    `json:"id"` //通过指定 tag 实现 json 序列化该字段时的 key
    Gender string `json:"gender"`
    Name   string
    Sno    string
}

func main() {
    var s1 = Student{
       ID: 1, Gender: "男", Name: "李四", Sno: "s0001"}
    fmt.Printf("%#v\n", s1)
    var s, _ = json.Marshal(s1)
    jsonStr := string(s)
    fmt.Println(jsonStr)
}

输出结果:

main.Student{ID:1, Gender:"男", Name:"李四", Sno:"s0001"}
{"id":1,"gender":"男","Name":"李四","Sno":"s0001"}
package main

import (
    "encoding/json"
    "fmt"
)

type Student struct {
    ID     int    `json:"id"` //通过指定 tag 实现 json 序列化该字段时的 key
    Gender string `json:"gender"`
    Name   string
    Sno    string
}

func main() {
    var s2 Student
    var str = "{\"id\":1,\"gender\":\"男\",\"Name\":\"李四\",\"Sno\":\"s0001\"}"
    err := json.Unmarshal([]byte(str), &s2)
    if err != nil {
       fmt.Println(err)
    }
    fmt.Printf("%#v", s2)
}

输出结果:

main.Student{ID:1, Gender:"男", Name:"李四", Sno:"s0001"}

# 四、嵌套结构体和 JSON 序列化反序列化

package main

import (
    "encoding/json"
    "fmt"
)

// Student 学生
type Student struct {
    ID     int
    Gender string
    Name   string
}

// Class 班级
type Class struct {
    Title    string
    Students []Student
}

func main() {
    c := &Class{
       Title: "001", Students: make([]Student, 0, 200)}
    for i := 0; i < 10; i++ {
       stu := Student{
          Name: fmt.Sprintf("stu%02d", i), Gender: "男", ID: i}
       c.Students = append(c.Students, stu)
    }
    //JSON 序列化:结构体-->JSON 格式的字符串
    data, err := json.Marshal(c)
    if err != nil {
       fmt.Println("json marshal failed")
       return
    }
    fmt.Printf("json:%s\n", data)
}

输出结果:

json:{"Title":"001","Students":[{"ID":0,"Gender":"男","Name":"stu00"},{"ID":1,"Gender":"男","Name":"stu01"},{"ID":2,"Gender":"男","Name":"stu02"},{"ID":3,"Gender":"男","Name":"stu03"},{"ID":4,"Gender":"男","Name":"stu04"},{"ID":5,"Gender":"男","Name":"stu05"},{"ID":6,"Gender":"男","Name":"stu06"},{"ID":7,"Gender":"男","Name":"stu07"},{"ID":8,"Gender":"男","Name":"stu08"},{"ID":9,"Gender":"男","Name":"stu09"}]}
package main

import (
    "encoding/json"
    "fmt"
)

// Student 学生
type Student struct {
    ID     int
    Gender string
    Name   string
}

// Class 班级
type Class struct {
    Title    string
    Students []Student
}

func main() {
    str := `{
  "Title": "001",
  "Students": [
    { "ID": 0, "Gender": "男", "Name": "stu00" },
    { "ID": 1, "Gender": "男", "Name": "stu01" },
    { "ID": 2, "Gender": "男", "Name": "stu02" },
    { "ID": 3, "Gender": "男", "Name": "stu03" },
    { "ID": 4, "Gender": "男", "Name": "stu04" },
    { "ID": 5, "Gender": "男", "Name": "stu05" },
    { "ID": 6, "Gender": "男", "Name": "stu06" },
    { "ID": 7, "Gender": "男", "Name": "stu07" },
    { "ID": 8, "Gender": "男", "Name": "stu08" },
    { "ID": 9, "Gender": "男", "Name": "stu09" }
  ]
}`
    c1 := &Class{}
    err := json.Unmarshal([]byte(str), c1)
    if err != nil {
       fmt.Println("json unmarshal failed!")
       return
    }
    fmt.Printf("%#v\n", c1)
}

输出结果:

&main.Class{Title:"001", Students:[]main.Student{main.Student{ID:0, Gender:"男", Name:"stu00"}, main.Student{ID:1, Gender:"男", Name:"stu01"}, main.Student{ID:2, Gender:"男", Name:"stu02"}, main.Student{ID:3, Gen:"男", Name:"stu03"}, main.Student{ID:4, Gender:"男", Name:"04"}, main.Student{ID:5, Gender:"男", Name:"stu05"}, main.Student{ID:6, Gender:"男", Name:"stu06"}, main.Student{ID:7, Gender:"男", Name:"stu07"}, main.nt{ID:8, Gender:"男", Name:"stu08"}, main.Student{ID:9, Gender:"男", Name:"stu09"}}}

# 五、关于 Map、切片的序列化反序列化

Map 和切片也可以进行序列化和反序列化,在讲完接口后再去给大家详细讲解

上次更新: 2025/03/22, 00:19:03
Golang中的结构体详解
Golang 中的 go mod 以及 Golang 包详解

← Golang中的结构体详解 Golang 中的 go mod 以及 Golang 包详解→

Theme by Vdoing | Copyright © 2022-2025 Salmon's Blog
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式