自学内容网 自学内容网

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)!