Go中reflect包不能直接创建新对象,但可通过reflect.New(返回指针零值)、reflect.Zero(返回不可寻址零值)或调用工厂函数实现动态实例化,前提是有已知类型和导出字段。
在 Go 中,reflect 包不支持直接“创建新对象”,但可以通过反射获取类型信息、调用构造函数或初始化零值结构体,实现动态实例化。关键在于:你得有类型(reflect.Type)或已有实例(reflect.Value),再用 reflect.New 或 reflect.Zero 等方法生成新值。
这是最常用、最安全的动态创建方式,适用于已知类型(如结构体、切片、map 等):
reflect.New(t) 返回一个 reflect.Value,其底层是 *T 类型的指针,指向该类型的零值.Interface() 可转为真实 Go 指针(如 *MyStruct)示例:
type User struct { Name string; Age int }当你只需要一个不可修改的零值(比如传参、比较、占
位),可用 reflect.Zero:
reflect.Zero(t) 返回 reflect.Value,对应类型 T 的零值(非指针).CanAddr() == false),不能用 .SetXxx 修改map[string]int{} 或 []byte(nil)
示例:
t := reflect.TypeOf([]int{})Go 没有内置构造函数语法,但约定俗成用 NewXXX 或 XXX{} 初始化。若想反射调用类似 NewUser() 的函数:
go:linkname,生产慎用)func() interface{}
reflect.Value.Call([]reflect.Value{}) 执行并获取返回值示例(简单工厂):
var constructors = map[string]func() interface{}{Go 的 struct 字面量(如 User{})是编译期语法,运行时无法反射生成。常见误区:
reflect.New(reflect.TypeOf((*interface{})(nil)).Elem()) —— 得到的是 *interface{},不是任意类型reflect.MakeMap 等创建具体类型实例前,必须先有 reflect.Type,不能靠字符串自动解析类型reflect.Type → reflect.New / reflect.Zero / 工厂函数基本上就这些。反射实例化不复杂,但容易忽略“类型必须已知”和“字段可见性”两个前提。