dougu7546 2015-10-15 22:59
浏览 40
已采纳

反射匿名结构字段指针

I have a struct like this

type duration struct {
    time.Duration
}

and another one like that

type Config struct {
    Announce duration
}

I am using reflection to assign flags to the fields of the struct Config. However, with the particular use case of the type duration, i am stuck. The problem is that when i do a switch type, i got *config.duration instead of *time.Duration. How can i access the anonymous field ?

Here is the full code

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)
            }
        }
    }
}

Thanks

  • 写回答

1条回答 默认 最新

  • doupo1865 2015-10-15 23:45
    关注

    Okay, after some digging, and thanks to my IDE, i found that using a method elem() on ptr who return a pointer *time.Duration do the trick. It also work if i directly use &ptr.Duration

    Here is the working code.

    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)
                }
            }
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法