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.
Go struct access fields The struct fields are accessed with the dot operator. We create an empty User struct. We initialize the fields with values and read them using the dot operator.
A struct is a user-defined type that contains a collection of fields. It is used to group related data to form a single unit. A Go struct can be compared to a lightweight class without the inheritance feature. A struct tag is additional meta data information inserted into struct fields.
An optional identifier, called a "tag," gives the name of the structure type and can be used in subsequent references to the structure type. A variable of that structure type holds the entire sequence defined by that type.
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.
You can play with an example here.
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))
}
https://play.golang.org/p/Sb0i7za5Uow
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With