[英]How to use reflect to set every field of struct to non-nil value in go
假設我有一些類型,我想實例化一個這種類型的變量,每個值都不是零。
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)
}
但是,運行此代碼后,事件變量中的所有字段仍設置為 nil。 我怎樣才能達到我想要的?
reflect
package 需要一個指向該結構的指針才能設置其字段。 還需要導出字段,您可以使用CanSet
方法對其進行檢查。
要使用reflect
初始化指針類型,您可以簡單地執行reflect.New(T.Elem())
。 要將map
、 slice
、 func
或chan
類型初始化為非零類型,您可以分別使用MakeMap
、 MakeSlice
、 MakeFunc
和MakeChan
函數。 要將接口類型初始化為非零,您可以使用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
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.