在 go 语言中使用 encoding/json 包解析 JSON 数据时,经常会遇到 int64 类型的字段值为 null 的情况。直接将 null 值 unmarshal 到 int64 类型的变量会导致错误,因为 int64 类型无法表示 null。本文将介绍一种有效的解决方案:使用 *int64 指针类型。
使用 *int64 指针类型
Go 语言中的指针类型可以表示一个值的地址,也可以为 nil。 因此,我们可以使用 *int64 类型来表示一个可能为 null 的 int64 值。 当 JSON 中的值为 null 时,*int64 类型的变量会被 unmarshal 为 nil;当 JSON 中的值为一个有效的 int64 数字时,*int64 类型的变量会指向一个包含该数字的 int64 值。
下面是一个示例代码:
package main import ( "encoding/json" "fmt" ) var d = []byte(`{ "world":[{"data": 2251799813685312}, {"data": null}]}`) type jsonobj struct { World []World } type World struct { Data *int64 `json:"data"` } func main() { var data jsonobj jerr := json.Unmarshal(d, &data) fmt.Println(jerr) fmt.Println(data) // 访问数据 for _, w := range data.World { if w.Data == nil { fmt.Println("Data is null") } else { fmt.Println("Data:", *w.Data) // 注意:需要解引用指针 } } }
代码解释:
- *`type World struct { Data int64 `json:”data”` }**: 我们将Data字段的类型从int64修改为*int64。json:”data”tag 确保 JSON 解析器能正确地将 JSON 中的 “data” 字段 unmarshal 到Data` 字段。
- if w.Data == nil { … } else { … }: 在访问 Data 字段的值之前,我们需要检查它是否为 nil。 如果是 nil,则表示 JSON 中的值为 null。
- *`fmt.Println(“Data:”, w.Data)**: 如果Data字段不为nil,则我们需要使用*` 运算符来解引用指针,以获取实际的 int64 值。
运行结果:
<nil> {[{0x1400011a000} {<nil>}]} Data: 2251799813685312 Data is null
可以看到,null 值被成功地 unmarshal 为 nil,并且我们可以通过判断指针是否为 nil 来确定 JSON 中的值是否为 null。
注意事项
-
解引用指针前必须检查 nil: 在使用 *int64 类型的变量之前,务必先检查它是否为 nil,否则会导致 panic。
-
默认值: 如果希望将 null 值转换为特定的默认值(例如 -1),可以在 unmarshal 后进行手动处理。 例如:
for i := range data.World { if data.World[i].Data == nil { defaultValue := int64(-1) data.World[i].Data = &defaultValue } }
总结
使用 *int64 指针类型是处理 JSON 中 int64 类型字段值为 null 的一种有效方法。 它可以让我们在 Go 语言中优雅地处理 null 值,并避免 unmarshal 错误。 通过本文提供的示例代码和注意事项,相信你能够更好地处理 JSON 数据中的 null 值。