【问题标题】:Get struct Tag with reflection - Error: type reflect.Value has no field or method Tag使用反射获取结构标记 - 错误:类型 reflect.Value 没有字段或方法标记
【发布时间】:2021-02-12 11:08:01
【问题描述】:

假设我们有这个PoC

package main

import (
        "fmt"
        "reflect"
        "strings"
)

type MyStruct struct {
        Str string `gorm:"size:10" json:"string"`
}

func main() {
        aStruct := MyStruct{"Hello"}

        s := reflect.ValueOf(&aStruct).Elem()
        if s.Kind() == reflect.Struct {
                for i := 0; i < s.NumField(); i++ {
                        field := s.Field(i)
                        if field.IsValid() {
                                if field.CanSet() {
                                        fmt.Printf("%T\n", field)  // reflect.Value, need reflect.StructField
                                        gormTag := field.Tag.Get("gorm")  // Compile ERROR HERE
                                        gormSize := strings.Split(gormTag, "size:")[1]
                                        fmt.Println(gormSize)
                                }
                        }
                }
        }
}

错误是:

go run test1.go 
# command-line-arguments
./test1.go:22:22: field.Tag undefined (type reflect.Value has no field or method Tag)

使用 go 1.14.6 和 go 1.15.2 测试。

据我了解,我需要将reflect.Value 转换为(或从中获取)reflect.StructField 任何想法如何做到这一点?

【问题讨论】:

    标签: go struct reflection introspection


    【解决方案1】:

    标签属于结构体字段的类型,不属于结构体类型的

    reflect.ValueOf() 返回的包装,而不是它的类型。要获取标签值,您需要从类型的包装器开始,例如通过reflect.TypeOf()获得:

    t := reflect.TypeOf(&aStruct).Elem()
    

    以及循环中字段的类型包装器(类型为reflect.StructTag):

    field := s.Field(i)
    fieldt := t.Field(i)
    

    并使用fieldt获取标签:

    gormTag := fieldt.Tag.Get("gorm") // No error, this works
    

    添加后,输出将是(在Go Playground 上尝试):

    reflect.Value
    10
    

    查看相关:What are the use(s) for tags in Go?

    【讨论】:

      猜你喜欢
      • 2021-11-01
      • 2021-02-22
      • 2022-06-29
      • 1970-01-01
      • 2015-09-13
      • 1970-01-01
      • 2022-11-10
      • 1970-01-01
      相关资源
      最近更新 更多