[英]How to use reflect to set every field of struct to non-nil value in go
Suppose I have some type, and I want to instantiate a variable of this type, with every value non-nil.假设我有一些类型,我想实例化一个这种类型的变量,每个值都不是零。
type Event struct {
HappenedAtMs int64
ReceivedAtMs int64
FieldA *FieldAType
FieldB []*FieldBType
Here is what I am currently trying:这是我目前正在尝试的:
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)
}
However, upon running this code, all the fields in the event variable are still set to nil.但是,运行此代码后,事件变量中的所有字段仍设置为 nil。 How can I achieve what I want?
我怎样才能达到我想要的?
The reflect
package needs a pointer to the struct for it to be able to set its fields. reflect
package 需要一个指向该结构的指针才能设置其字段。 The fields also need to be exported which you can check against using the CanSet
method.还需要导出字段,您可以使用
CanSet
方法对其进行检查。
To initialize a pointer type with reflect
you can simply do reflect.New(T.Elem())
.要使用
reflect
初始化指针类型,您可以简单地执行reflect.New(T.Elem())
。 To initialize a map
, a slice
, a func
, or a chan
type to non-nil you can use the MakeMap
, MakeSlice
, MakeFunc
, and MakeChan
functions respectively.要将
map
、 slice
、 func
或chan
类型初始化为非零类型,您可以分别使用MakeMap
、 MakeSlice
、 MakeFunc
和MakeChan
函数。 To initialize an interface type to non-nil you can create an anonymous struct type, using reflect.StructOf
, with a single embedded field of the target interface type, by embedding the interface type the struct type automatically satisfies the interface and an instance of it can be used to set the field to non-nil.要将接口类型初始化为非零,您可以使用
reflect.StructOf
创建一个匿名结构类型,其中包含目标接口类型的单个嵌入字段,通过嵌入接口类型,结构类型自动满足接口及其实例可用于将字段设置为非零。
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
}
}
}
https://play.golang.com/p/nQqvUIROqF- https://play.golang.com/p/nQqvUIROqF-
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.