Is it possible to reflect on a field of a struct, and get a reference to its tag values?
For example:
type User struct {
name string `json:name-field`
age int
}
// ...
user := &User{"John Doe The Fourth", 20}
getStructTag(user.name)
// ...
func getStructTag(i interface{}) string{
//get tag from field
}
From what I can see, the usual way to do this is to range over typ.NumField()
, and then call field.Tag.Get("tagname")
.
However, in my use-case, it would be much better to not have to pass the whole struct in.
You don't need to pass in the whole struct, but passing in the value of one of the fields is not sufficient.
In your example user.name
field is just a string
- the reflect package will have no way of correlating that back to the original struct.
Instead, you need to pass around the reflect.StructField
for the given field:
field, ok := reflect.TypeOf(user).Elem().FieldByName("name")
…
tag = string(field.Tag)
Note: we use Elem
above because user
is a pointer to a struct.
Modifying the above answer can give value of a specific tag
package main
import (
"fmt"
"reflect"
)
type User struct {
Name string `json:"name_field"`
Age int
}
func main() {
user := &User{"John Doe The Fourth", 20}
field, ok := reflect.TypeOf(user).Elem().FieldByName("Name")
if !ok {
panic("Field not found")
}
fmt.Println(getStructTag(field, "json")) //name_field
}
func getStructTag(f reflect.StructField, tagName string) string {
return string(f.Tag.Get(tagName))
}
Clean way to list all tags from a struct (using external lib).
External lib: https://github.com/fatih/structs
Example: https://go.dev/play/p/C_yXMdbFYAq
package main
import (
"fmt"
"github.com/fatih/structs"
)
type User struct {
Name string `json:"name_field"`
Age int `json:"age_field"`
}
func main() {
user := &User{}
fields := structs.Fields(user)
for _, field := range fields {
tag := field.Tag("json")
fmt.Println(tag)
}
}
Result:
name_field
age_field
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.