Go语言JSON自动解析time.Time的源码位置、格式及自定义解析咨询
Go JSON 自动解析与自定义解析问题解答
1. time.Time 的 JSON 解析逻辑在源码中的位置
Go 中 time.Time 类型的 JSON 反序列化逻辑主要由两部分实现:
time.Time本身实现了json.Unmarshaler接口,对应的UnmarshalJSON方法定义在time/time.go文件中,负责核心的时间字符串解析逻辑。encoding/json包的decode.go文件里,convertTime函数会调用上述方法,完成从 JSON 字符串到time.Time类型的转换。
2. 支持的时间格式
time.Time 的 JSON 解析主要支持 RFC3339 标准格式,包含以下常见变体:
- 基础格式:
"2006-01-02T15:04:05Z07:00" - 带小数秒的格式:
"2006-01-02T15:04:05.999Z07:00"(小数部分支持任意位数) - 若字符串不带时区信息,解析时会默认使用本地时区尝试解析。
3. 其他可自动解析的 JSON 字符串类型
除了 time.Time,encoding/json 包还支持将 JSON 字符串自动解析到以下类型:
- 基础数据类型:
int/int64、float64、bool、string - 复合类型:切片(
[]T)、映射(map[string]interface{})、结构体 - 特殊类型:
[]byte(自动解码 Base64 编码的字符串) - 所有实现了
json.Unmarshaler接口的自定义类型
4. 自定义 JSON 解析逻辑
完全可以自定义解析逻辑,只需让目标类型实现 json.Unmarshaler 接口即可。针对你给出的场景,实现方式如下:
首先为 Bar 类型实现 UnmarshalJSON 方法:
import ( "encoding/json" "strconv" "strings" ) type Foo struct { Foo Bar `json:"foo"` } type Bar struct { Words []string } func (b *Bar) UnmarshalJSON(data []byte) error { // 移除 JSON 字符串的引号 s, err := strconv.Unquote(string(data)) if err != nil { return err } // 按下划线分割字符串并赋值给 Words b.Words = strings.Split(s, "_") return nil }
使用示例:
func main() { jsonData := []byte(`{"foo": "my_own_format"}`) var f Foo if err := json.Unmarshal(jsonData, &f); err != nil { panic(err) } // 输出: [my own format] println(strings.Join(f.Foo.Words, " ")) }
调用 json.Unmarshal 时,会自动触发自定义解析逻辑,将下划线分隔的字符串转换为 Bar.Words 数组。
内容的提问来源于stack exchange,提问作者Andrew Arrow
相关产品推荐
相关产品推荐

