📅  最后修改于: 2023-12-03 15:08:37.309000             🧑  作者: Mango
在 Golang 中解析 JSON 可以使用内置的 encoding/json 包,该包提供了 Unmarshal 函数来将 JSON 数据映射到 Golang 中的 struct 类型中。以下是解析 JSON 数据的详细步骤。
首先,需要定义一个 struct
来表示要解析的 JSON 数据结构。例如,如果要解析以下 JSON 数据:
{
"name": "Alice",
"age": 30,
"isMarried": true,
"hobbies": ["reading", "traveling"]
}
则可以定义如下 struct
:
type Person struct {
Name string
Age int
IsMarried bool
Hobbies []string
}
注意,struct
中的字段名需要首字母大写,这样才能被 encoding/json 包识别并解析。
使用 json.Unmarshal
函数将 JSON 数据解析成 Person
对象。
jsonData := []byte(`{
"name": "Alice",
"age": 30,
"isMarried": true,
"hobbies": ["reading", "traveling"]
}`)
person := Person{}
err := json.Unmarshal(jsonData, &person)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Name: %s\n", person.Name)
fmt.Printf("Age: %d\n", person.Age)
fmt.Printf("Is married: %t\n", person.IsMarried)
fmt.Printf("Hobbies: %v\n", person.Hobbies)
上述代码中,json.Unmarshal
函数将第一个参数 jsonData
解析成 Person
对象,并将结果存储在第二个参数 &person
中。如果出现错误,则会返回非 nil 的错误值。
如果 JSON 数据不符合预期,例如包含了未知字段或类型不匹配等错误,json.Unmarshal
函数会返回一个解析错误,需要对错误进行处理。
jsonData := []byte(`{
"name": "Alice",
"age": "30", // 这里将 age 字段设为字符串类型
"isMarried": true,
"hobbies": ["reading", "traveling"],
"address": {
"city": "Shanghai",
"country": "China"
}
}`)
person := Person{}
err := json.Unmarshal(jsonData, &person)
if err != nil {
if e, ok := err.(*json.UnmarshalTypeError); ok {
log.Printf("Type error: expected %v but got %v", e.Type, e.Value)
} else if e, ok := err.(*json.InvalidUnmarshalError); ok {
log.Printf("Invalid unmarshal error: %v", e)
} else {
log.Printf("JSON parsing error: %v", err)
}
}
上述代码中,如果解析错误是类型不匹配,则会输出 "Type error: expected int but got string"
。如果 Person
中的某个字段不可导出,则会输出 "Invalid unmarshal error: json: cannot unmarshal object into Go struct field Person.address of type string"
。对于其他类型的解析错误,将输出 "JSON parsing error: <error message>"
。
有时候,JSON 数据可能包含未知的字段。为了避免出错,需要通过 json.RawMessage
类型来处理这些未知字段。
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
IsMarried bool `json:"isMarried"`
Hobbies []string `json:"hobbies"`
RawFields json.RawMessage `json:"-"`
}
上述代码中,Person
中增加了一个 RawFields
字段,用来存储未知的 JSON 字段。json:",-"
表示该字段不需要进行 JSON 解析映射。
jsonData := []byte(`{
"name": "Alice",
"age": 30,
"isMarried": true,
"hobbies": ["reading", "traveling"],
"address": {
"city": "Shanghai",
"country": "China"
}
}`)
person := Person{}
err := json.Unmarshal(jsonData, &person)
if err != nil {
log.Printf("JSON parsing error: %v", err)
}
fmt.Printf("Name: %s\n", person.Name)
fmt.Printf("Age: %d\n", person.Age)
fmt.Printf("Is married: %t\n", person.IsMarried)
fmt.Printf("Hobbies: %v\n", person.Hobbies)
fmt.Printf("Raw fields: %s\n", string(person.RawFields))
上述代码中,person.RawFields
字段将包含未知的 JSON 字段 "address"
。
Golang 提供了内置的 encoding/json 包处理 JSON 数据。以创建数据类型映射的方式来解析 JSON 数据,将 JSON 数据解析到 struct 中可以更方便地使用它。错误处理和未知字段处理也是必要的注意点。