从Go结构体中提取标签作为reflect.Value。

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

Extract tags from Go struct as a reflect.Value

问题

我正在尝试从一个名为Value的结构体中提取标签。我能够获取结构体的字段,但无法提取标签。我在这里做错了什么?我尝试了许多不同的方法(使用reflect.Type、interface{}等),但都失败了。

type House struct {
    Room string
    Humans Human
}

type Human struct {
    Name         string `anonymize:"true"` // 无法获取此标签
    Body         string
    Tail         string `anonymize:"true"` // 无法获取此标签
}

func printStructTags(f reflect.Value) { // f 是类型为`Human`的结构体
    for i := 0; i < f.NumField(); i++ {
        fmt.Printf("标签为 %s\n", reflect.TypeOf(f).Field(i).Tag) // 标签没有被打印出来
    }
}

我将reflect.Value作为参数是因为这个函数是从另一个函数中以以下方式调用的:

var payload interface{}
payload = &House{}
// 设置完成
v := reflect.ValueOf(payload).Elem()
for j := 0; j < v.NumField(); j++ { // 遍历payload的所有字段
    f := v.Field(j)
    if f.Kind().String() == "struct" {
        printStructTags(f)
    }
}

任何见解都将非常宝贵。

英文:

I'm trying to extract tags from a certain Value which is a struct. I am able to get the fields of the struct but unable to extract the tags. What am I doing wrong here? I've tried many different ways (using reflect.Type, interface{} etc) but all failed.


type House struct {
    Room string
    Humans Human
}

type Human struct {
	Name         string `anonymize:&quot;true&quot;` // Unable to get this tag
	Body         string
	Tail         string `anonymize:&quot;true&quot;` // Unable to get this tag
}

func printStructTags(f reflect.Value) { // f is of struct type `human`
	for i := 0; i &lt; f.NumField(); i++ {
		fmt.Printf(&quot;Tags are %s\n&quot;, reflect.TypeOf(f).Field(i).Tag) // TAGS AREN&#39;T PRINTED
	}
}

The reason I use reflect.Value as the parameter is because this function is called from another function in the following manner

    var payload interface{}
    payload = &amp;House{}
    // Setup complete
    v := reflect.ValueOf(payload).Elem()
	for j := 0; j &lt; v.NumField(); j++ { // Go through all fields of payload
		f := v.Field(j)
        if f.Kind().String() == &quot;struct&quot; { 
			printStructTags(f)
        }
    }

Any insights would be extremely valuable

答案1

得分: 3

当你调用reflect.TypeOf(f)时,你会得到f的类型,它已经是一个reflect.Value

使用fType()函数来获取类型并对其进行字段检查:

func printStructTags(f reflect.Value) { // f是结构体类型`human`
    for i := 0; i < f.NumField(); i++ {
        fmt.Printf("Tags are %s\n", f.Type().Field(i).Tag) 
    }
}

然而,更容易的方法是使用f.Type().Field(i).Tag.Get("anonymize")来检查标签并获取其值。这样你可以直接得到分配的值,例如在你的情况下是true,如果标签不存在则得到一个空字符串。

英文:

When you call reflect.TypeOf(f) you get the type of f, which is already a reflect.Value.

Use the Type() func of this f to get the type and do the Field check on it:

func printStructTags(f reflect.Value) { // f is of struct type `human`
	for i := 0; i &lt; f.NumField(); i++ {
		fmt.Printf(&quot;Tags are %s\n&quot;, f.Type().Field(i).Tag) 
	}
}

However, it's easier to check for a tag and get its value with f.Type().Field(i).Tag.Get(&quot;anonymize&quot;). This way you directly get the assigned value, for example true in your case and an empty string if the tag doesn't exist.

huangapple
  • 本文由 发表于 2022年4月29日 20:47:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/72058220.html
匿名

发表评论

匿名网友

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

确定