是否可以反映一个结构体的字段,并获得对其标记值的引用?
例如: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
}
从我所看到的,通常这样做的方法是覆盖typ.NumField()
,然后调用field.Tag.Get("tagname")
。
但是,在我的用例中,最好不要传递整个结构体
您不需要传入整个结构体,但是传入其中一个字段的值是不够的。
在您的示例中,user.name
字段只是string
-反射包将无法将其与原始结构相关联。
reflect.StructField
:
field, ok := reflect.TypeOf(user).Elem().FieldByName("name")
…
tag = string(field.Tag)
注意:我们在上面使用Elem
是因为user
是一个指向结构体的指针。
修改上述答案可以给出特定标签的值
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 清晰地列出结构体中的所有标签(使用外部库)。
外部库:https://github.com/fatih/structs
示例: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)
}
}
结果:name_field
age_field