Skip to content

Instantly share code, notes, and snippets.

@chen3feng
Created August 28, 2025 02:58
Show Gist options
  • Select an option

  • Save chen3feng/451aa39720645950c975abe637ef8ff8 to your computer and use it in GitHub Desktop.

Select an option

Save chen3feng/451aa39720645950c975abe637ef8ff8 to your computer and use it in GitHub Desktop.
Struct to map in Go
import (
"reflect"
"strings"
"gopkg.in/yaml.v3"
)
// StructToMap converts a struct to a map[string]any recursively.
func StructToMap(s any, tagKey string) map[string]any {
out := make(map[string]any)
val := reflect.ValueOf(s)
typ := reflect.TypeOf(s)
if val.Kind() == reflect.Ptr {
val = val.Elem()
typ = typ.Elem()
}
for i := 0; i < val.NumField(); i++ {
field := typ.Field(i)
fieldVal := val.Field(i).Interface()
// Skip unexported fields
if !val.Field(i).CanInterface() {
continue
}
fieldName := getFieldName(field, tagKey)
// Handle nested struct
fv := val.Field(i)
switch fv.Kind() {
case reflect.Struct:
out[fieldName] = StructToMap(fv.Interface(), tagKey)
case reflect.Ptr:
if !fv.IsNil() && fv.Elem().Kind() == reflect.Struct {
out[fieldName] = StructToMap(fv.Interface(), tagKey)
} else {
out[fieldName] = fv.Interface()
}
default:
out[fieldName] = fieldVal
}
}
return out
}
func getFieldName(field reflect.StructField, tagKey string) string {
// read field tag
name := field.Name
if tagKey == "" {
return name
}
tag := field.Tag.Get(tagKey)
if tag != "" && tag != "-" {
parts := strings.Split(tag, ",")
if parts[0] != "" {
name = parts[0]
}
}
return name
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment