插件窝 干货文章 Go语言JSON解析:如何无需预定义结构体灵活处理JSON数据?

Go语言JSON解析:如何无需预定义结构体灵活处理JSON数据?

JSON Println err skills 46    来源:    2025-03-14

在Go语言中,通常我们使用结构体来解析JSON数据,因为结构体能够提供明确的字段映射。然而,如果你需要在不预定义结构体的情况下灵活处理JSON数据,可以使用map[string]interface{}encoding/json包中的json.RawMessage来实现。

方法1:使用 map[string]interface{}

map[string]interface{} 可以用来解析任意结构的JSON数据。JSON对象会被解析为一个map,其中键是字符串,值是interface{}类型,可以进一步转换为具体的类型。

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    jsonData := `{
        "name": "John",
        "age": 30,
        "is_student": false,
        "skills": ["Go", "Python", "JavaScript"],
        "address": {
            "city": "New York",
            "zipcode": "10001"
        }
    }`

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

    // 访问数据
    name := data["name"].(string)
    age := data["age"].(float64) // JSON中的数字默认解析为float64
    isStudent := data["is_student"].(bool)
    skills := data["skills"].([]interface{})
    address := data["address"].(map[string]interface{})

    fmt.Println("Name:", name)
    fmt.Println("Age:", age)
    fmt.Println("Is Student:", isStudent)
    fmt.Println("Skills:", skills)
    fmt.Println("City:", address["city"])
}

方法2:使用 json.RawMessage

json.RawMessage 可以用来延迟解析JSON数据。你可以先将整个JSON数据解析为json.RawMessage,然后再根据需要逐步解析。

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    jsonData := `{
        "name": "John",
        "age": 30,
        "is_student": false,
        "skills": ["Go", "Python", "JavaScript"],
        "address": {
            "city": "New York",
            "zipcode": "10001"
        }
    }`

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

    // 逐步解析
    var name string
    if err := json.Unmarshal(data["name"], &name); err != nil {
        fmt.Println("Error unmarshalling name:", err)
        return
    }

    var age int
    if err := json.Unmarshal(data["age"], &age); err != nil {
        fmt.Println("Error unmarshalling age:", err)
        return
    }

    var isStudent bool
    if err := json.Unmarshal(data["is_student"], &isStudent); err != nil {
        fmt.Println("Error unmarshalling is_student:", err)
        return
    }

    var skills []string
    if err := json.Unmarshal(data["skills"], &skills); err != nil {
        fmt.Println("Error unmarshalling skills:", err)
        return
    }

    var address map[string]string
    if err := json.Unmarshal(data["address"], &address); err != nil {
        fmt.Println("Error unmarshalling address:", err)
        return
    }

    fmt.Println("Name:", name)
    fmt.Println("Age:", age)
    fmt.Println("Is Student:", isStudent)
    fmt.Println("Skills:", skills)
    fmt.Println("City:", address["city"])
}

总结

  • map[string]interface{}:适合处理简单的、结构不固定的JSON数据,但需要手动进行类型断言。
  • json.RawMessage:适合需要逐步解析JSON数据的场景,能够更灵活地控制解析过程。

根据你的需求选择合适的方法来处理JSON数据。