Reputation: 2845
Let's say we have this 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)
}
}
}
}
}
The error is:
go run test1.go
# command-line-arguments
./test1.go:22:22: field.Tag undefined (type reflect.Value has no field or method Tag)
Tested with go 1.14.6 and go 1.15.2.
In my understanding I need to cast (or get from) reflect.Value
to reflect.StructField
Any ideas how to do that?
Upvotes: 0
Views: 3406
Reputation: 418227
The tags belong to the type of fields of the struct, not to the values of the struct type.
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()
And the type wrapper of the field in the loop (which will be of type reflect.StructTag
):
field := s.Field(i)
fieldt := t.Field(i)
And use fieldt
to get the tag:
gormTag := fieldt.Tag.Get("gorm") // No error, this works
With this addition, output will be (try it on the Go Playground):
reflect.Value
10
See related: What are the use(s) for tags in Go?
Upvotes: 2