如何使用reflect将go中struct的每个字段设置为非nil值

如何使用reflect将go中struct的每个字段设置为非nil值,go,Go,假设我有某种类型,我想实例化这种类型的变量,每个值都不是nil type Event struct { HappenedAtMs int64 ReceivedAtMs int64 FieldA *FieldAType FieldB []*FieldBType 以下是我目前正在尝试的: eventFields := reflect.TypeOf(Event{}) event := Event{}

假设我有某种类型,我想实例化这种类型的变量,每个值都不是nil

type Event struct {
    HappenedAtMs   int64 
    ReceivedAtMs   int64
    FieldA         *FieldAType
    FieldB         []*FieldBType

以下是我目前正在尝试的:

    eventFields := reflect.TypeOf(Event{})

    event := Event{}
    for i := 0; i < eventFields.NumField(); i++ {
        nonEmptyType := reflect.New(eventFields.Field(i).Type).Elem()
        reflect.ValueOf(&event).Elem().Field(i).Set(nonEmptyType)
    }
eventFields:=reflect.TypeOf(事件{})
事件:=事件{}
对于i:=0;i

但是,在运行此代码时,事件变量中的所有字段仍然设置为nil。如何实现我想要的?

反射
包需要指向结构的指针才能设置其字段。还需要导出字段,您可以使用
CanSet
方法进行检查

要使用
reflect
初始化指针类型,只需执行
reflect.New(T.Elem())
。要将
map
slice
func
chan
类型初始化为非零,可以分别使用
MakeMap
MakeSlice
MakeFunc
MakeChan
函数。要将接口类型初始化为非nil,您可以使用
reflect.StructOf
,创建一个匿名结构类型,其中包含一个目标接口类型的嵌入字段,通过嵌入接口类型,结构类型会自动满足接口,并且可以使用它的实例将字段设置为非nil

event := Event{}

rv := reflect.ValueOf(&event).Elem()
for i := 0; i < rv.NumField(); i++ {
    if f := rv.Field(i); isNilable(f) && f.IsNil() && f.CanSet() {
        switch f.Kind() {
        case reflect.Ptr:
            f.Set(reflect.New(f.Type().Elem()))
        case reflect.Slice:
            f.Set(reflect.MakeSlice(f.Type(), 0, 0))
        case reflect.Interface:
            sf := reflect.StructField{
                Name:      f.Type().Name(),
                Type:      f.Type(),
                Anonymous: true,
            }
            rt := reflect.StructOf([]reflect.StructField{sf})
            f.Set(reflect.New(rt).Elem())
            // TODO handle the rest of nilable types
        }
    }
}
event:=事件{}
rv:=reflect.ValueOf(&event).Elem()
对于i:=0;i