英文:
Get struct field tag using Go reflect package
问题
在Go语言中,可以通过反射来获取结构体字段的标签值。以下是一个示例:
package main
import (
"fmt"
"reflect"
)
type User struct {
name string `json:"name-field"`
age int
}
func main() {
user := &User{"John Doe The Fourth", 20}
tag := getStructTag(user, "name")
fmt.Println(tag)
}
func getStructTag(i interface{}, fieldName string) string {
t := reflect.TypeOf(i).Elem()
field, _ := t.FieldByName(fieldName)
return field.Tag.Get("json")
}
在上面的示例中,我们定义了一个User
结构体,其中name
字段有一个json
标签。getStructTag
函数接收一个接口类型和字段名作为参数,使用反射获取字段的标签值。
请注意,由于user
是一个指针类型,我们需要使用reflect.TypeOf(i).Elem()
来获取指针指向的结构体类型。
运行上述代码,将输出name-field
,即name
字段的标签值。
希望对你有帮助!
英文:
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.
答案1
得分: 78
你不需要传递整个结构体,但仅传递一个字段的值是不够的。
在你的例子中,user.name
字段只是一个string
类型 - 反射包无法将其与原始结构体关联起来。
相反,你需要传递给定字段的reflect.StructField
:
field, ok := reflect.TypeOf(user).Elem().FieldByName("name")
…
tag := string(field.Tag)
注意:我们在上面使用Elem
是因为user
是一个指向结构体的指针。
英文:
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.
答案2
得分: 10
修改上面的答案可以给出特定标签的值
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
英文:
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))
}
答案3
得分: 2
从结构体中列出所有标签的清晰方法(使用外部库)。
外部库: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
英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论