实用反射:序列化器
使用 reflect 构建简单的类 JSON 序列化器
实用反射:序列化器 是 CoddyKit 上的免费 Go Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Go Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Go Academy 课程共包含 4 节课。
自定义 JSON 序列化器概览
使用反射构建自定义序列化器,可以展示反射的实际应用:遍历结构体字段、读取标签、访问值并构建输出——encoding/json 内部也采用了相同的方法。
简单的结构体转映射
使用反射将结构体转换为 map[string]any:
func StructToMap(v any) map[string]any {
t := reflect.TypeOf(v)
val := reflect.ValueOf(v)
result := make(map[string]any, t.NumField())
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
if !f.IsExported() { continue }
key := f.Tag.Get("json")
if key == "" { key = f.Name }
result[key] = val.Field(i).Interface()
}
return result
}处理指针
读取指针字段的值之前,先对其进行解引用:
fv := val.Field(i)
if fv.Kind() == reflect.Ptr {
if fv.IsNil() { continue }
fv = fv.Elem()
}处理嵌套结构体
递归处理嵌套的结构体字段:
if fv.Kind() == reflect.Struct {
result[key] = StructToMap(fv.Interface())
continue
}支持 omitempty
如果标签包含 "omitempty",请跳过零值字段:
if strings.Contains(tag, "omitempty") && fv.IsZero() { continue }映射转结构体(反序列化器)
通过将映射键与字段标签匹配,从映射填充结构体:
func MapToStruct(m map[string]any, dest any) {
t := reflect.TypeOf(dest).Elem()
v := reflect.ValueOf(dest).Elem()
for i := 0; i < t.NumField(); i++ {
key := t.Field(i).Tag.Get("json")
if val, ok := m[key]; ok {
v.Field(i).Set(reflect.ValueOf(val))
}
}
}类型强制转换
来自 JSON 的映射值通常会将数字表示为 float64。设置字段时,请将其转换为目标字段类型:
if f.Type.Kind() == reflect.Int && reflect.TypeOf(val).Kind() == reflect.Float64 {
v.Field(i).SetInt(int64(val.(float64)))
}缓存字段元数据
将字段到标签的映射缓存到以 reflect.Type 为键的 sync.Map 中,避免每次序列化调用都重复进行反射。
代码生成替代方案
对于性能关键路径,请使用 easyjson 或 ffjson 等工具生成特定类型的序列化器。它们完全避免了运行时反射。
何时构建自定义序列化器
以下情况适合使用自定义序列化器:非 JSON 格式(BSON、Avro、CSV)、自定义编码规则或严格的性能要求。对于大多数用例,encoding/json 已经足够。
测试序列化器
往返测试:将结构体序列化为映射,再反序列化回来,并断言值与原始值匹配:
u := User{Name: "Alice", Age: 30}
m := StructToMap(u)
var u2 User
MapToStruct(m, &u2)
assert.Equal(t, u, u2)快速检查
构建基于反射的序列化器时,为什么字段元数据缓存很重要?
回顾:基于反射的序列化器
要点:
- 使用 NumField/Field 遍历字段;使用 Tag.Get 读取标签
- 处理指针、嵌套结构体和零值
- 为提升性能,在 sync.Map 中缓存字段元数据
- 使用代码生成可获得最高吞吐量
常见问题解答
「实用反射:序列化器」课时是免费的吗?
是的 — 「实用反射:序列化器」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Go Academy 课程的其余内容,请升级到 CoddyKit PRO。 Go Academy 课程共包含 4 节课。
「实用反射:序列化器」这节课中我会学到什么?
使用 reflect 构建简单的类 JSON 序列化器 你通过在浏览器中直接运行的动手代码来练习 Go Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Go Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Go Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「实用反射:序列化器」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Go Academy 课中编写并运行代码吗?
能。每节 Go Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。