📅  最后修改于: 2023-12-03 15:31:01.025000             🧑  作者: Mango
在 Golang 中解析 JSON 数据非常容易,只需要使用内置的 encoding/json
包就可以了。
让我们从一个简单的例子开始,假设我们有如下的 JSON 数据:
{
"Name": "John Doe",
"Age": 30,
"Email": "john.doe@example.com",
"Address": {
"Street": "123 Main St",
"City": "Anytown",
"State": "CA",
"ZipCode": "12345"
},
"PhoneNumbers": [
{
"Type": "Home",
"Number": "555-555-1111"
},
{
"Type": "Work",
"Number": "555-555-2222"
}
]
}
我们可以使用 Unmarshal()
函数将上述 JSON 数据解析成一个 Go 结构体:
type Person struct {
Name string
Age int
Email string
Address Address
PhoneNumbers []PhoneNumber
}
type Address struct {
Street string
City string
State string
ZipCode string
}
type PhoneNumber struct {
Type string
Number string
}
func main() {
jsonStr := `
{
"Name": "John Doe",
"Age": 30,
"Email": "john.doe@example.com",
"Address": {
"Street": "123 Main St",
"City": "Anytown",
"State": "CA",
"ZipCode": "12345"
},
"PhoneNumbers": [
{
"Type": "Home",
"Number": "555-555-1111"
},
{
"Type": "Work",
"Number": "555-555-2222"
}
]
}`
var person Person
err := json.Unmarshal([]byte(jsonStr), &person)
if err != nil {
fmt.Println(err)
}
fmt.Printf("%+v", person)
}
输出结果为:
{Name:"John Doe", Age:30, Email:"john.doe@example.com", Address:{Street:"123 Main St", City:"Anytown", State:"CA", ZipCode:"12345"}, PhoneNumbers:[{Type:"Home", Number:"555-555-1111"}, {Type:"Work", Number:"555-555-2222"}]}
当 JSON 数据不符合规范时,例如 JSON 字段中缺少必需的字段或格式错误时,json.Unmarshal()
函数将返回一个错误。
你可以使用 json.Decoder
类型来将 JSON 字段解析为 Token
,并使用 Token
类型来访问字段。以下是一个例子:
type Person struct {
Name string
Age int
Email string
Address Address
PhoneNumbers []PhoneNumber
}
type Address struct {
Street string
City string
State string
ZipCode string
}
type PhoneNumber struct {
Type string
Number string
}
func main() {
jsonStr := `
{
"Name": "John Doe",
"Age": 30,
"Address": {
"City": "Anytown",
"State": "CA",
"ZipCode": "12345"
}
}`
var person Person
decoder := json.NewDecoder(strings.NewReader(jsonStr))
for {
token, err := decoder.Token()
if err == io.EOF {
break
}
if err != nil {
fmt.Println(err)
}
if key, ok := token.(string); ok && key == "Name" {
decoder.Decode(&person.Name)
}
if key, ok := token.(string); ok && key == "Age" {
decoder.Decode(&person.Age)
}
if key, ok := token.(string); ok && key == "Email" {
decoder.Decode(&person.Email)
}
if key, ok := token.(string); ok && key == "Address" {
decoder.Decode(&person.Address)
}
if key, ok := token.(string); ok && key == "PhoneNumbers" {
decoder.Decode(&person.PhoneNumbers)
}
}
fmt.Printf("%+v", person)
}
与解析 JSON 数据相反,我们可以使用 Marshal()
函数将结构体转换为 JSON 格式的字符串:
type Person struct {
Name string
Age int
Email string
Address Address
PhoneNumbers []PhoneNumber
}
type Address struct {
Street string
City string
State string
ZipCode string
}
type PhoneNumber struct {
Type string
Number string
}
func main() {
person := Person{
Name: "John Doe",
Age: 30,
Email: "john.doe@example.com",
Address: Address{
Street: "123 Main St",
City: "Anytown",
State: "CA",
ZipCode: "12345",
},
PhoneNumbers: []PhoneNumber{
{Type: "Home", Number: "555-555-1111"},
{Type: "Work", Number: "555-555-2222"},
},
}
jsonBytes, err := json.Marshal(person)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(jsonBytes))
}
输出结果为:
{"Name":"John Doe","Age":30,"Email":"john.doe@example.com","Address":{"Street":"123 Main St","City":"Anytown","State":"CA","ZipCode":"12345"},"PhoneNumbers":[{"Type":"Home","Number":"555-555-1111"},{"Type":"Work","Number":"555-555-2222"}]}
在解析或生成 JSON 数据时,encoding/json
包还支持一些有用的特性:
json:"myField"
可以匹配 JSON 中的 MyField
、myField
、MYFIELD
等字段名)nil
,这样就可以检测 JSON 中是否存在该字段)json.Unmarshaler
和 json.Marshaler
接口以支持特定的 JSON 表示形式。json:",omitempty"
相应的字段可以被忽略。Golang 提供了方便的 JSON 解析和编码功能,使处理 JSON 数据变得简单和直观。同时 encoding/json
包也具有一些有用的特性,可以更方便地处理 JSON 数据。