第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

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

使用反射程序?qū)⒔Y(jié)構(gòu)字段綁定到命令行標(biāo)志值

使用反射程序?qū)⒔Y(jié)構(gòu)字段綁定到命令行標(biāo)志值

Go
月關(guān)寶盒 2023-01-03 11:16:10
我有幾個配置結(jié)構(gòu),我想自動將其解析為可接受的命令行標(biāo)志(以允許用戶通過 CLI 覆蓋它們)。鑒于結(jié)構(gòu)可能會隨著時間的推移而演變,并且其中一個結(jié)構(gòu)是interface{},反射似乎是正確的方法。我只需要解析字符串、整數(shù)和 float64。我得到了以下工作:func ReconGenerateFlags(in *ReconConfig, cmd *cobra.Command) {    for _, f := range reflect.VisibleFields(reflect.TypeOf(*in)) {        group_name := f.Name        v := reflect.ValueOf(in).Elem().FieldByName(f.Name).Elem() // Return the concrete substructures pointed to by "in"        sub_fields := reflect.VisibleFields(v.Type())        for _, sub_f := range sub_fields {            tag_name := sub_f.Name            sub_v := v.FieldByName(tag_name)            full_flag_name := strings.ToLower(group_name) + "." + strings.ToLower(tag_name)            switch s := sub_v.Type().String(); s {            case "string":                ptr := (*string)(unsafe.Pointer(sub_v.UnsafeAddr()))                cmd.Flags().StringVar(ptr, flag_name, "", "")            case "int":                ptr := (*int)(unsafe.Pointer(sub_v.UnsafeAddr()))                cmd.Flags().IntVar(ptr, flag_name, 0, "")            //case "float64":            //  ptr := (*float64)(unsafe.Pointer(sub_v.UnsafeAddr()))            //  cmd.Flags().Float64Var(ptr, flag_name, 0.0, "")            default:                fmt.Printf("unrecognized type in config setup: %s\n", s)            }        }    }}但是當(dāng)我取消注釋 float64 塊時,我感到恐慌:panic: reflect.Value.UnsafeAddr of unaddressable valuegoroutine 1 [running]:reflect.Value.UnsafeAddr(...)    /usr/local/go/src/reflect/value.go:2526所以,我的具體問題是“有沒有辦法使它適用于 float64s?”,我稍微寬泛的問題是“有沒有更好的反射方法不需要不安全的指針轉(zhuǎn)換?”我更愿意完全尊重類型系統(tǒng),但如何通過反射做到這一點并不明顯。另一種選擇似乎是代碼生成,我想避免這種情況,但如果需要可以爭論。在此先感謝您的任何輸入!
查看完整描述

1 回答

?
波斯汪

TA貢獻(xiàn)1811條經(jīng)驗 獲得超4個贊

如果我正確理解了您的要求,那么就沒有必要使用unsafe. 要獲取指向字段的指針,您只需使用Value.Addr方法和類型斷言來獲取具體類型。

func GenerateFlags(in interface{}, fs *flag.FlagSet, names []string) {

    rv := reflect.ValueOf(in)

    if rv.Kind() != reflect.Ptr || rv.Elem().Kind() != reflect.Struct {

        return // exit if not pointer-to-a-struct

    }


    rv = rv.Elem()

    rt := rv.Type()

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

        sf := rt.Field(i)

        fv := rv.Field(i)

        name := strings.Join(append(names, strings.ToLower(sf.Name)), ".")


        switch fv.Type() {

        case reflect.TypeOf(string("")):

            p := fv.Addr().Interface().(*string)

            fs.StringVar(p, name, "", "")

        case reflect.TypeOf(int(0)):

            p := fv.Addr().Interface().(*int)

            fs.IntVar(p, name, 0, "")

        case reflect.TypeOf(float64(0)):

            p := fv.Addr().Interface().(*float64)

            fs.Float64Var(p, name, 0, "")

        default:

            names := append([]string{}, names...)

            GenerateFlags(fv.Interface(), fs, append(names, strings.ToLower(sf.Name)))

        }

    }

}

https://go.dev/play/p/1F2Kyo0cBuj


查看完整回答
反對 回復(fù) 2023-01-03
  • 1 回答
  • 0 關(guān)注
  • 124 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號