反射匿名结构字段指针



我有一个像这样的结构体

type duration struct {
    time.Duration
}

和另一个类似的

type Config struct {
    Announce duration
}

我正在使用反射来为配置结构的字段分配标志。但是,对于类型duration的特定用例,我被卡住了。问题是,当我做一个开关类型,我得到*config.duration而不是*time.Duration。如何访问匿名字段?

这是完整的代码

func assignFlags(v interface{}) {
    // Dereference into an adressable value
    xv := reflect.ValueOf(v).Elem()
    xt := xv.Type()
    for i := 0; i < xt.NumField(); i++ {
        f := xt.Field(i)
        // Get tags for this field
        name := f.Tag.Get("long")
        short := f.Tag.Get("short")
        usage := f.Tag.Get("usage")
        addr := xv.Field(i).Addr().Interface()
        // Assign field to a flag
        switch ptr := addr.(type) { // i get `*config.duration` here
        case *time.Duration:
            if len(short) > 0 {
                // note that this is not flag, but pflag library. The type of the first argument muste be `*time.Duration`
                flag.DurationVarP(ptr, name, short, 0, usage)
            } else {
                flag.DurationVar(ptr, name, 0, usage)
            }
        }
    }
}

谢谢

好吧,经过一番挖掘,感谢我的IDE,我发现在ptr上使用方法elem()返回一个指针*time.Duration可以做到这一点。它也工作,如果我直接使用&ptr.Duration

下面是工作代码。

func (d *duration) elem() *time.Duration {
    return &d.Duration
}
func assignFlags(v interface{}) {
    // Dereference into an adressable value
    xv := reflect.ValueOf(v).Elem()
    xt := xv.Type()
    for i := 0; i < xt.NumField(); i++ {
        f := xt.Field(i)
        // Get tags for this field
        name := f.Tag.Get("long")
        short := f.Tag.Get("short")
        usage := f.Tag.Get("usage")
        addr := xv.Field(i).Addr().Interface()
        // Assign field to a flag
        switch ptr := addr.(type) {
        case *duration:
            if len(short) > 0 {
                flag.DurationVarP(ptr.elem(), name, short, 0, usage)
            } else {
                flag.DurationVar(ptr.elem(), name, 0, usage)
            }
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新