当前位置: 首页 > article >正文

Go的JSON转化

在Go语言中,处理JSON(JavaScript Object Notation)数据非常常见,特别是在与Web服务交互时。Go提供了内置的encoding/json包来支持JSON的序列化(将Go对象转换为JSON格式)和反序列化(将JSON格式的数据解析为Go对象)。

1. JSON的序列化和反序列化

1.1 序列化(结构体转换为JSON)

将Go结构体转换为JSON格式使用json.Marshal函数。

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

func main() {
	// 初始化结构体
	p := Person{Name: "Alice", Age: 30}

	// 将结构体转换为JSON
	jsonData, err := json.Marshal(p)
	if err != nil {
		fmt.Println("Error marshaling JSON:", err)
		return
	}

	// 输出JSON数据
	fmt.Println(string(jsonData)) // {"name":"Alice","age":30}
}
1.2 反序列化(JSON转换为结构体)

将JSON数据转换为Go结构体使用json.Unmarshal函数。

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

func main() {
	// JSON数据
	jsonData := `{"name": "Bob", "age": 25}`

	// 反序列化JSON到结构体
	var p Person
	err := json.Unmarshal([]byte(jsonData), &p)
	if err != nil {
		fmt.Println("Error unmarshaling JSON:", err)
		return
	}

	// 输出结构体
	fmt.Println(p) // {Bob 25}
}

2. 处理map类型的JSON

JSON对象可以表示为Go的map类型,其中键是字符串,值可以是任意类型。对于动态的或不确定结构的数据,使用map[string]interface{}

2.1 将map转换为JSON
package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	// 使用map表示JSON数据
	data := map[string]interface{}{
		"name": "Charlie",
		"age":  28,
		"hobbies": []string{"Reading", "Cycling"},
	}

	// 将map转换为JSON
	jsonData, err := json.Marshal(data)
	if err != nil {
		fmt.Println("Error marshaling JSON:", err)
		return
	}

	// 输出JSON数据
	fmt.Println(string(jsonData))
}
2.2 将JSON转换为map
package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	// JSON数据
	jsonData := `{"name": "Diana", "age": 35, "hobbies": ["Music", "Traveling"]}`

	// 创建一个空的map
	var data map[string]interface{}

	// 将JSON数据反序列化到map
	err := json.Unmarshal([]byte(jsonData), &data)
	if err != nil {
		fmt.Println("Error unmarshaling JSON:", err)
		return
	}

	// 输出map数据
	fmt.Println(data) // map[age:35 hobbies:[Music Traveling] name:Diana]
}

3. JSON标签(struct tags)

Go语言中的结构体字段可以使用标签(tags)来指定JSON中的字段名。常见的用法是为结构体字段添加json标签,以定义序列化时的字段名。

3.1 设置字段名
package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	Name    string `json:"name"`
	Age     int    `json:"age"`
	Address string `json:"address,omitempty"` // omitempty表示如果字段值为空则不序列化
}

func main() {
	p := Person{Name: "Eva", Age: 30}

	// 将结构体转为JSON
	jsonData, err := json.Marshal(p)
	if err != nil {
		fmt.Println("Error marshaling JSON:", err)
		return
	}

	fmt.Println(string(jsonData)) // {"name":"Eva","age":30}
}
3.2 使用omitempty标签

omitempty标签使得字段在为空时不进行JSON序列化。对于指针类型、字符串、数组、切片和数字类型,当其值为零值时,omitempty会忽略该字段。

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	Name    string `json:"name"`
	Age     int    `json:"age"`
	Address string `json:"address,omitempty"`
}

func main() {
	p := Person{Name: "Grace", Age: 25}

	// 序列化为JSON
	jsonData, err := json.Marshal(p)
	if err != nil {
		fmt.Println("Error marshaling JSON:", err)
		return
	}

	fmt.Println(string(jsonData)) // {"name":"Grace","age":25}
}

4. 格式化输出(美化JSON)

可以使用json.MarshalIndent将JSON格式化输出,使其更易读(带有缩进)。

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	Name    string `json:"name"`
	Age     int    `json:"age"`
	Address string `json:"address"`
}

func main() {
	p := Person{Name: "Hannah", Age: 28, Address: "London"}

	// 美化输出
	jsonData, err := json.MarshalIndent(p, "", "    ")
	if err != nil {
		fmt.Println("Error marshaling JSON:", err)
		return
	}

	fmt.Println(string(jsonData))
}

输出:

{
    "name": "Hannah",
    "age": 28,
    "address": "London"
}

5. 处理JSON中的空值和类型不匹配

Go中的interface{}类型允许在JSON反序列化时处理不同类型的数据。需要小心处理类型不匹配的情况。

5.1 空字段的处理

对于空值或没有定义的字段,在反序列化时可以忽略,或者通过结构体标签设置为零值。

5.2 类型断言

如果反序列化后的数据类型是interface{},你需要使用类型断言来访问具体类型的值。

package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	// JSON数据
	jsonData := `{"name": "Ivy", "age": 33, "active": true}`

	var data map[string]interface{}
	err := json.Unmarshal([]byte(jsonData), &data)
	if err != nil {
		fmt.Println("Error unmarshaling JSON:", err)
		return
	}

	// 使用类型断言
	if age, ok := data["age"].(float64); ok {
		fmt.Println("Age:", age)
	} else {
		fmt.Println("Age is missing or not a number")
	}

	// 直接访问布尔类型
	if active, ok := data["active"].(bool); ok {
		fmt.Println("Active:", active)
	}
}

6. 将JSON字符串映射到数组或切片

Go支持将JSON数据映射到数组或切片中,适用于处理JSON数组。

示例:JSON数组到Go切片
package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	// JSON数组
	jsonData := `[
		{"name": "Jack", "age": 25},
		{"name": "Tom", "age": 28},
		{"name": "Alice", "age": 30}
	]`

	// 创建切片并解析JSON数据
	var people []map[string]interface{}
	err := json.Unmarshal([]byte(jsonData), &people)
	if err != nil {
		fmt.Println("Error unmarshaling JSON:", err)
		return
	}

	// 输出数据
	for _, person := range people {
		fmt.Println(person)
	}
}
  • 序列化:使用json.Marshal将Go对象转换为JSON。
  • 反序列化:使用json.Unmarshal将JSON数据解析为Go对象。
  • 标签:可以使用json标签指定字段名,并使用omitempty控制字段是否为空时不序列化。
  • 格式化:使用json.MarshalIndent生成格式化输出。
  • 空值和类型断言:通过interface{}和类型断言处理复杂的JSON数据。
  • 切片和数组:支持将JSON数组解析为Go切片。

http://www.kler.cn/a/385118.html

相关文章:

  • Vue 自定义icon组件封装SVG图标
  • STM32外设之SPI的介绍
  • Spring配置文件初始化加载(二)
  • 杨辉三角,洗牌算法
  • Spark 的介绍与搭建:从理论到实践
  • vue实现websocket实时短消息通知
  • 论文2—《基于柔顺控制的智能神经导航手术机器人系统设计》文献阅读分析报告
  • 北斗智能定位平板终端|三防平板|北斗有源终端|北斗搜救终端
  • keil-C51 linux下开发小记
  • 在实际的网络通信中,客户端发起请求的常见流程
  • DeFi 4.0峥嵘初现:主权金融时代的来临
  • 【案例】Excel使用宏来批量插入图片
  • Aop+自定义注解实现数据字典映射
  • SQL(2)
  • C#-内部类、分部类、分部方法
  • 融合虚拟化与容器技术,打造灵活又安全的AI算力服务
  • leetcode 2043.简易银行系统
  • 线性代数中的核心数学知识
  • maven推送jar到本地和远程仓库
  • 2024年大湾区杯粤港澳金融数学建模赛题浅析——助攻快速选题
  • HTMLCSS:旋转的动态卡片
  • 1.python介绍、安装
  • 如何使用函数模板和类模板?
  • 拓展题:viple计算n!
  • Docker可视化管理面板DPanel的安装
  • Ubuntu20.04离线安装nginx