Created
August 28, 2025 02:58
-
-
Save chen3feng/451aa39720645950c975abe637ef8ff8 to your computer and use it in GitHub Desktop.
Struct to map in Go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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