反射匿名结构体字段指针

huangapple go评论104阅读模式
英文:

Reflection anonymous struct field pointer

问题

我有一个类似这样的结构体:

type duration struct {
    time.Duration
}

还有一个类似这样的结构体:

type Config struct {
    Announce duration
}

我正在使用反射将标志分配给结构体Config的字段。然而,在类型为duration的特定用例中,我遇到了问题。问题是,当我使用switch语句判断类型时,我得到的是*config.duration而不是*time.Duration。我该如何访问匿名字段?

以下是完整的代码:

func assignFlags(v interface{}) {

    // 将其解引用为可寻址的值
    xv := reflect.ValueOf(v).Elem()
    xt := xv.Type()

    for i := 0; i < xt.NumField(); i++ {
        f := xt.Field(i)

        // 获取此字段的标签
        name := f.Tag.Get("long")
        short := f.Tag.Get("short")
        usage := f.Tag.Get("usage")

        addr := xv.Field(i).Addr().Interface()

        // 将字段分配给标志
        switch ptr := addr.(type) { // 在这里我得到的是`*config.duration`
        case *time.Duration:
            if len(short) > 0 {
                // 注意这不是flag,而是pflag库。第一个参数的类型必须是`*time.Duration`
                flag.DurationVarP(ptr, name, short, 0, usage)
            } else {
                flag.DurationVar(ptr, name, 0, usage)
            }
        }
    }
}

希望对你有帮助!

英文:

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 &lt; xt.NumField(); i++ {
		f := xt.Field(i)

		// Get tags for this field
		name := f.Tag.Get(&quot;long&quot;)
		short := f.Tag.Get(&quot;short&quot;)
		usage := f.Tag.Get(&quot;usage&quot;)

		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) &gt; 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

得分: 2

好的,以下是翻译好的内容:

好的,在进行一些调查后,借助我的IDE,我发现在ptr上使用elem()方法,它会返回一个指向*time.Duration的指针,这样就可以解决问题。如果直接使用&ptr.Duration也可以工作。

以下是可工作的代码:

func (d *duration) elem() *time.Duration {
    return &d.Duration
}

func assignFlags(v interface{}) {

    // 解引用为可寻址的值
    xv := reflect.ValueOf(v).Elem()
    xt := xv.Type()

    for i := 0; i < xt.NumField(); i++ {
        f := xt.Field(i)

        // 获取该字段的标签
        name := f.Tag.Get("long")
        short := f.Tag.Get("short")
        usage := f.Tag.Get("usage")

        addr := xv.Field(i).Addr().Interface()

        // 将字段分配给标志
        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)
            }
        }
    }
}

希望对你有帮助!

英文:

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 &amp;ptr.Duration

Here is the working code.

func (d *duration) elem() *time.Duration {
	return &amp;d.Duration
}

func assignFlags(v interface{}) {

	// Dereference into an adressable value
	xv := reflect.ValueOf(v).Elem()
	xt := xv.Type()

	for i := 0; i &lt; xt.NumField(); i++ {
		f := xt.Field(i)

		// Get tags for this field
		name := f.Tag.Get(&quot;long&quot;)
		short := f.Tag.Get(&quot;short&quot;)
		usage := f.Tag.Get(&quot;usage&quot;)

		addr := xv.Field(i).Addr().Interface()

		// Assign field to a flag
		switch ptr := addr.(type) {
		case *duration:
			if len(short) &gt; 0 {
				flag.DurationVarP(ptr.elem(), name, short, 0, usage)
			} else {
				flag.DurationVar(ptr.elem(), name, 0, usage)
			}
		}
	}
}

huangapple
  • 本文由 发表于 2015年10月16日 06:59:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/33159923.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定