使用Go反射包获取结构体字段标签

问题描述 投票:0回答:3

是否可以反映结构体的字段,并获取对其标签值的引用?

例如:

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")

但是,在我的用例中,最好不必传递整个结构。

reflection struct go
3个回答
80
投票

您不需要传入整个结构体,但传入其中一个字段的值是不够的。

在您的示例中,

user.name
字段只是一个
string
- 反射包将无法将其关联回原始结构。

相反,您需要传递给定字段的

reflect.StructField

field, ok := reflect.TypeOf(user).Elem().FieldByName("name")
…
tag = string(field.Tag)

注意:我们在上面使用

Elem
,因为
user
是指向结构体的指针。

您可以在这里玩一个示例。


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 f.Tag.Get(tagName)
}

https://play.golang.org/p/Sb0i7za5Uow


3
投票

列出结构中所有标签的简洁方法(使用外部库)。

外部库: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
© www.soinside.com 2019 - 2024. All rights reserved.