我正在尝试递归解析表单数据字典到一个嵌入式结构中。它是 kindof 工作的,但最终只有一个字段得到设置。我认为该字段一直被旧结构覆盖,但需要一些帮助来找到解决方案。
函数的入口点:
func FormDataToStruct(data map[string]string, s any) {
// Parse the form data into the struct
v := reflect.ValueOf(s)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
if v.Kind() != reflect.Struct {
panic("not a struct")
}
formParse(data, v, s)
}
设置最顶层结构的值:
func formParse(data map[string]string, v reflect.Value, s any) {
for key, value := range data {
if hasField(v, key) {
println("Found field: " + key)
var val, err = TransformValue(s, key, value)
if err != nil {
panic(err)
}
SetValue(s, key, val)
delete(data, key)
}
}
// Set values of inner structs
for key, value := range data {
keys := strings.Split(key, "_")
// Parse the inner struct recursively with another function
recurseKeys(keys, value, v, s, s)
}
}
结构如下所示:
type Me struct {
Name string
Age int
Friend struct {
Name string
Age int
}
}
要分析的表单数据如下所示:
一个三个三个一个
通过该结构运行上述表单数据将产生以下输出:
println(meInstance)
// {John 20 {Jane 0}}
任何帮助都是非常感谢!
- 编辑 *
使用最少的可重复示例进行Playground游戏:https://go.dev/play/p/d5pIK3uQrUL
1条答案
按热度按时间2ledvvac1#
这段代码的问题在于它创建了一个新的struct并用现有的对象替换它。因此,你总是会看到最后一次赋值。
代码的修复版本如下所示:
这段代码也接受结构指针。
性能改进提示:您可能需要考虑扫描目标对象并创建
name -> Reflect value
的贴图以减少循环数。保养提示:最好考虑使用struct tags,而不是直接反映结构变量名。