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

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

Extract tags from Go struct as a reflect.Value

问题

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

  1. type House struct {
  2. Room string
  3. Humans Human
  4. }
  5. type Human struct {
  6. Name string `anonymize:"true"` // 无法获取此标签
  7. Body string
  8. Tail string `anonymize:"true"` // 无法获取此标签
  9. }
  10. func printStructTags(f reflect.Value) { // f 是类型为`Human`的结构体
  11. for i := 0; i < f.NumField(); i++ {
  12. fmt.Printf("标签为 %s\n", reflect.TypeOf(f).Field(i).Tag) // 标签没有被打印出来
  13. }
  14. }

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

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

任何见解都将非常宝贵。

英文:

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.

  1. type House struct {
  2. Room string
  3. Humans Human
  4. }
  5. type Human struct {
  6. Name string `anonymize:&quot;true&quot;` // Unable to get this tag
  7. Body string
  8. Tail string `anonymize:&quot;true&quot;` // Unable to get this tag
  9. }
  10. func printStructTags(f reflect.Value) { // f is of struct type `human`
  11. for i := 0; i &lt; f.NumField(); i++ {
  12. fmt.Printf(&quot;Tags are %s\n&quot;, reflect.TypeOf(f).Field(i).Tag) // TAGS AREN&#39;T PRINTED
  13. }
  14. }

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

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

Any insights would be extremely valuable

答案1

得分: 3

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

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

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

然而,更容易的方法是使用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:

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

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:

确定