繁体   English   中英

如何在golang中获取结构的json字段名称?

[英]How to get the json field names of a struct in golang?

获取此结构的 json 字段名称的方法是什么?

type example struct {
    Id          int `json:"id"`
    CreatedAt   string `json:"created_at"`
    Tag         string `json:"tag"`
    Text        string `json:"text"`
    AuthorId    int `json:"author_id"`
}

我尝试使用此 function 打印字段:

func (b example) PrintFields() {
    val := reflect.ValueOf(b)
    for i := 0; i < val.Type().NumField(); i++ {
        fmt.Println(val.Type().Field(i).Name)
    }
}

我当然得到:

Id
CreatedAt
Tag
Text
AuthorId

但我想要类似的东西:

id
created_at
tag
text
author_id

您可以使用StructTag类型来获取标签。 我链接的文档有示例,查找它们,但您的代码可能类似于

func (b example) PrintFields() {
  val := reflect.ValueOf(b)
  for i := 0; i < val.Type().NumField(); i++ {
     fmt.Println(val.Type().Field(i).Tag.Get("json"))
  }
}

注意json标记格式不仅仅支持字段名称,例如omitemptystring ,因此如果您也需要一种方法来处理这些问题,则应进一步改进PrintFields函数:

  1. 我们需要检查json标签是否为- (即json:"-"
  2. 我们需要检查名称是否存在并隔离它

像这样的东西:

func (b example) PrintFields() {
  val := reflect.ValueOf(b)
  for i := 0; i < val.Type().NumField(); i++ {
    t := val.Type().Field(i)
    fieldName := t.Name

    switch jsonTag := t.Tag.Get("json"); jsonTag {
    case "-":
    case "":
        fmt.Println(fieldName)
    default:
        parts := strings.Split(jsonTag, ",")
        name := parts[0]
        if name == "" {
            name = fieldName
        }
        fmt.Println(name)
    }
  }
}

您可以使用Tag来获取StructTag对象,而不是使用StructFieldName 请参阅: https : //golang.org/pkg/reflect/#StructTag

然后你可以使用StructTagGetLookup方法来获取 json 标签:

使用Get

func (b example) PrintFields() {
    val := reflect.ValueOf(b)
    for i := 0; i < val.Type().NumField(); i++ {
        // prints empty line if there is no json tag for the field
        fmt.Println(val.Type().Field(i).Tag.Get("json"))
    }
}

使用Lookup

func (b example) PrintFields() {
    val := reflect.ValueOf(b)
    for i := 0; i < val.Type().NumField(); i++ {
        // skips fields without json tag
        if tag, ok := val.Type().Field(i).Tag.Lookup("json"); ok {
            fmt.Println(tag)
        }
    }
}

采用:

func (b example) PrintFields() {
    val := reflect.ValueOf(b)
    t := val.Type()
    for i := 0; i < t.NumField(); i++ {
        fmt.Println(t.Field(i).Tag.Get("json"))
    }
}

操场上看到它

具有通用接口作为参数的更新版本:

func PrintFields(b interface{}) {
    val := reflect.ValueOf(b)
    for i := 0; i < val.Type().NumField(); i++ {
        t := val.Type().Field(i)
        fieldName := t.Name

        if jsonTag := t.Tag.Get("json"); jsonTag != "" && jsonTag != "-" {
            // check for possible comma as in "...,omitempty"
            var commaIdx int
            if commaIdx = strings.Index(jsonTag, ","); commaIdx < 0 {
                commaIdx = len(jsonTag)
            }
            fieldName = jsonTag[:commaIdx]
        }
        fmt.Println(fieldName)
    }
}

不是您要查找的Name 你看的是Tag

func (b example) PrintFields() {
    val := reflect.ValueOf(b)
    for i := 0; i < val.Type().NumField(); i++ {
        fmt.Println(val.Type().Field(i).Tag.Get("json"))
    }
}
func (e example) GetJsonField() []string {
    b := example{}
    marshaled, _ := json.Marshal(b)
    m := make(map[string]interface{})
    _ = json.Unmarshal(marshaled, &m)
    
    result := make([]string, 0)
    for k := range m {
        result = append(result, k)
    }
    return result
}

使用结构字段名称获取 Json 字段名称

val := reflect.ValueOf(structobject)    
field, _ := val.Type().FieldByName("Id")
fmt.Println(field.Tag.Get("json"))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM