Get struct Tag with reflection - Error: type reflect.Value has no field or method Tag

Get struct Tag with reflection - Error: type reflect.Value has no field or method Tag

假设我们有这个 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.Value 转换为 reflect.StructField 有什么想法吗?

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

reflect.ValueOf() returns you the wrapper of the value, not its type. To get the tag value, you need to start from the wrapper of the type, e.g. acquired with 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?