簡體   English   中英

如何使用反射將結構的每個字段設置為 go 中的非零值

[英]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()) 要將mapslicefuncchan類型初始化為非零類型,您可以分別使用MakeMapMakeSliceMakeFuncMakeChan函數。 要將接口類型初始化為非零,您可以使用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-

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM