反射与 unsafe
reflect 适用场景
在编译期类型未知时(如序列化库、依赖类型信息的 ORM),通过 reflect.Type / reflect.Value 在运行时检查结构。代价:失去编译期检查、性能与可读性下降,业务代码应优先用泛型或代码生成替代。
核心 API
go
t := reflect.TypeOf(x)
v := reflect.ValueOf(x)
Kind()区分底层种类(Struct、Ptr、Slice等)。- 可寻址值上
v.Set*修改;导出字段才可Set(CanSet)。 Interface()将reflect.Value还原为any。
结构体遍历
NumField() / Field(i) 遍历导出字段;匿名字段按提升规则展开。标签用 StructTag.Get("json") 等。
unsafe.Pointer 规则(摘录)
语言规范规定:unsafe.Pointer 与 uintptr 转换不能单独持有 uintptr 跨越可能使对象移动或回收的语句边界;典型反模式是把 uintptr 存进变量再在下一步转回指针。与 CGO、syscall 交互时严格按文档示例编写。
建议
反射用于框架层;应用层除 JSON 等标准路径外,避免用反射分支业务逻辑。需要多类型统一行为时优先泛型接口与 switch type 明确分支。