How to get json structure field names in golang?

What is the way to get json field names of this structure?

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"` } 

I am trying to print fields using this function:

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

Of course I get:

 Id CreatedAt Tag Text AuthorId 

But I would like something like:

 id created_at tag text author_id 
+11
source share
5 answers

You are using the StructTag type to retrieve tags. There are examples in the documentation I refer to, look at them, but your code might be something like

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

NOTE The json tag format supports more than just field names such as omitempty or string , so if you need an approach that also takes care of this, you need to make additional improvements to the PrintFields function:

  1. we need to check if the json tag - (ie json:"-" )
  2. we need to check if the name exists and isolate it

Something like that:

 func (b example) PrintFields() { 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 != "-" { if commaIdx := strings.Index(jsonTag, ","); commaIdx > 0 { fieldName = jsonTag[:commaIdx] } } fmt.Println(fieldName) } } 
+14
source

Instead of StructField Name you can use Tag to get the StructTag object. See: https://golang.org/pkg/reflect/#StructTag

Then you can use the StructTag Get or Lookup methods to get the json tag:

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

Using 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) } } } 
+4
source

Using:

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

Look at the playground.

+2
source

Not the Name you are looking for. What are you looking for 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")) } } 
+1
source

updated version with a universal interface as a parameter:

 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) } } 
0
source

Source: https://habr.com/ru/post/1012724/


All Articles