Skip to content

Instantly share code, notes, and snippets.

@maxsei
Created September 13, 2022 19:21
Show Gist options
  • Select an option

  • Save maxsei/7d1ea2f09d49f9241af7ea6b76981f53 to your computer and use it in GitHub Desktop.

Select an option

Save maxsei/7d1ea2f09d49f9241af7ea6b76981f53 to your computer and use it in GitHub Desktop.
error prone way of iterating through go struct tags as a map[string]string data structure in golang
package main
import (
"fmt"
"reflect"
"strings"
".../model"
)
func main() {
m := model.Topic{}
mv := reflect.ValueOf(m)
mt := mv.Type()
fmt.Printf("%v: %v\n", mt.Name(), mt)
for i := 0; i < mt.NumField(); i++ {
f := mt.Field(i)
fmt.Printf("\t%v: %v\n", f.Name, f.Type)
tags, err := GetTags(f.Tag)
if err != nil {
panic(err)
}
for k, v := range tags {
fmt.Printf("\t\t%s: %v\n", k, v)
}
}
}
func GetTags(tag reflect.StructTag) (map[string]string, error) {
t := string(tag)
ret := make(map[string]string)
for {
// Find single next key value pair in tag.
b := strings.Index(t, `:`)
if b == -1 {
break
}
a := 1 + strings.LastIndex(t[:b], ` `)
// Verify key value pair in tag.
// Wish go had something like this builtin to iterate over tags like a
// map...
k := t[a:b]
v, ok := tag.Lookup(k)
if !ok {
panic(fmt.Sprintf("key %v doesn't exist in tag: %v", k, tag))
}
ret[k] = v
// Next
t = strings.TrimSpace(t[b+1:])
}
return ret, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment