在Golang中处理JSON空值的关键是使用指针类型。指针可以区分"未设置"、“null"和"零值”。以下是具体实现:
package main
import (
"encoding/json"
"fmt"
)
type User struct {
ID int `json:"id"`
Name *string `json:"name"` // 使用指针
Age *int `json:"age"` // 使用指针
IsActive *bool `json:"isActive"` // 使用指针
}
func main() {
// JSON数据包含null值
jsonData := `{
"id": 1,
"name": null,
"age": null,
"isActive": null
}`
var user User
err := json.Unmarshal([]byte(jsonData), &user)
if err != nil {
panic(err)
}
// 检查各个字段
fmt.Printf("ID: %d\n", user.ID) // 1
if user.Name == nil {
fmt.Println("Name: null") // 输出: Name: null
} else {
fmt.Printf("Name: %s\n", *user.Name)
}
if user.Age == nil {
fmt.Println("Age: null") // 输出: Age: null
} else {
fmt.Printf("Age: %d\n", *user.Age)
}
if user.IsActive == nil {
fmt.Println("IsActive: null") // 输出: IsActive: null
} else {
fmt.Printf("IsActive: %v\n", *user.IsActive)
}
}
对于更复杂的场景,可以使用json.RawMessage:
package main
import (
"encoding/json"
"fmt"
)
type FlexibleUser struct {
ID int `json:"id"`
Metadata json.RawMessage `json:"metadata"` // 保留原始JSON
}
func main() {
jsonData := `{
"id": 1,
"metadata": null
}`
var user FlexibleUser
err := json.Unmarshal([]byte(jsonData), &user)
if err != nil {
panic(err)
}
fmt.Printf("ID: %d\n", user.ID)
fmt.Printf("Metadata (raw): %s\n", string(user.Metadata)) // 输出: null
// 检查是否为null
if string(user.Metadata) == "null" {
fmt.Println("Metadata is null")
}
}
使用sql.Null类型处理数据库空值:
package main
import (
"database/sql"
"encoding/json"
"fmt"
)
type Product struct {
ID int `json:"id"`
Price sql.NullFloat64 `json:"price"`
Name sql.NullString `json:"name"`
}
func (p Product) MarshalJSON() ([]byte, error) {
type Alias Product
aux := &struct {
*Alias
Price interface{} `json:"price"`
Name interface{} `json:"name"`
}{
Alias: (*Alias)(&p),
}
if p.Price.Valid {
aux.Price = p.Price.Float64
} else {
aux.Price = nil
}
if p.Name.Valid {
aux.Name = p.Name.String
} else {
aux.Name = nil
}
return json.Marshal(aux)
}
func main() {
product := Product{
ID: 1,
Price: sql.NullFloat64{Valid: false}, // null
Name: sql.NullString{String: "Laptop", Valid: true},
}
data, _ := json.Marshal(product)
fmt.Println(string(data)) // {"id":1,"price":null,"name":"Laptop"}
}
这些方法可以准确区分JSON中的null值和零值。