亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何將嵌套結構中的字段設置為零值?

如何將嵌套結構中的字段設置為零值?

Go
開心每一天1111 2022-04-26 14:32:01
假設我有一個Thing1我想要的 struct 實例json.Marshaltype Thing1 struct {    A string `json:"a,omitempty"`    B int    `json:"b,omitempty"`    C Thing2 `json:"c,omitempty"`}type Thing2 struct {    D bool `json:"d,omitempty"`    E int  `json:"e,omitempty"`}...thing1 := Thing1{    A: "test",    B: 42,    C: Thing2{D: true, E: 43},}您將如何編寫一個函數,該函數采用任何結構的實例和要編輯的字段列表并返回傳入對象的克?。ɑ蛑皇亲儺悾?,但將已編輯的字段設置為零值?redact(thing1, []string{"B", "D"})thing1 == Thing1{    A: "test",    B: 0,    C: Thing2{D: false, E: 43},}我不能json:"-"用作字段標簽,因為我正在使用的查詢語言(Dgraph)需要當前的標簽。編輯:不在示例中,但如果適用,還應編輯數組內的對象
查看完整描述

1 回答

?
aluckdog

TA貢獻1847條經驗 獲得超7個贊

使用反射來操作結構字段的值。以下是我在評論中寫的概念證明。由于這只是一個 poc,您可能需要調整/修改代碼以滿足您的需求。


這個函數改變原始數據。代碼是不言自明的。


func redact(target interface{}, fieldsToModify []string) {

    // if target is not pointer, then immediately return

    // modifying struct's field requires addresable object

    addrValue := reflect.ValueOf(target)

    if addrValue.Kind() != reflect.Ptr {

        return

    }


    // if target is not struct then immediatelly return

    // this might need to be modified as per your needs

    targetValue := addrValue.Elem()

    targetType := targetValue.Type()

    if targetType.Kind() != reflect.Struct {

        return

    }


    // loop the fields

    for i := 0; i < targetType.NumField(); i++ {

        fType := targetType.Field(i)

        fValue := targetValue.Field(i)


        // if the field type is struct, then call redact() recursively

        if fValue.Kind() == reflect.Struct {

            redact(fValue.Addr().Interface(), fieldsToModify)

            continue

        } 


        // if the field is slice, loop then call redact() recursively

        if fValue.Kind() == reflect.Array || fValue.Kind() == reflect.Slice {

            for i := 0; i < fValue.Len(); i++ {

                redact(fValue.Index(i).Addr().Interface(), fieldsToModify)

            }

            continue

        }


        // loop the fieldsToModify

        for _, fieldToModify := range fieldsToModify {

            if fieldToModify == fType.Name && fValue.CanSet() {

                fValue.Set(reflect.Zero(fType.Type))

            }

        }

    }

}

第一個參數中的redact()函數指針數據,因為修改字段需要可添加對象。


type Thing2 struct {

    D bool `json:"d,omitempty"`

    E int  `json:"e,omitempty"`

}


type Thing1 struct {

    A string   `json:"a,omitempty"`

    B int      `json:"b,omitempty"`

    C Thing2   `json:"c,omitempty"`

    H []Thing2 `json:"h,omitempty"`

}


thing1 := Thing1{

    A: "test",

    B: 42,

    C: Thing2{D: true, E: 43},

    H: []Thing2{Thing2{D: true, E: 43}},

}


fmt.Printf("before: %#v \n", thing1)

// before: main.Thing1{A:"test", B:42, C:main.Thing2{D:true, E:43}, H:[]main.Thing2{main.Thing2{D:true, E:43}}} 


redact(&thing1, []string{"B", "D"})

fmt.Printf("after: %#v \n", thing1)

// after: main.Thing1{A:"test", B:0, C:main.Thing2{D:false, E:43}, H:[]main.Thing2{main.Thing2{D:false, E:43}}} 

游樂場: https: //play.golang.org/p/wy39DGdSVV7


查看完整回答
反對 回復 2022-04-26
  • 1 回答
  • 0 關注
  • 125 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號