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切片。
原文地址:https://blog.csdn.net/weixin_44719499/article/details/143562115
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!