[gogf/gf]从结构体加载,反射参数有2层以上嵌套Struct时,将嵌套元素的值赋值给了主参数

2024-06-25 242 views
6

错误的代码位于gf/util/gconv/gconv_map.go:219,此处不应该是循环赋值,而应该是m[name]=doMapConvert(rvField.Interface(), recursive, tags...)

回答

4

@zmcity 能给复现问题的最小代码吗?

1
package main

import (
    "fmt"
    "github.com/gogf/gf/encoding/gjson"
)

type ModifyFieldInfoType struct {
    Id  int64  `json:"id"`
    New string `json:"new"`
}
type ModifyFieldInfosType struct {
    Duration  ModifyFieldInfoType `json:"duration"`
    OMLevel   ModifyFieldInfoType `json:"om_level"`
}

type FieldInfoType struct {
    Id    int64  `json:"id"`
    Value string `json:"value"`
}

type FieldInfosType struct {
    Duration  ModifyFieldInfoType `json:"duration"`
    OMLevel   ModifyFieldInfoType `json:"om_level"`
}

type MediaRequestModifyInfo struct {
    Modify    ModifyFieldInfosType `json:"modifyFieldInfos"`
    Field     ModifyFieldInfosType `json:"fieldInfos"`
    FeedID    string               `json:"feed_id"`
    Vid       string               `json:"id"`
}

var processQueue chan MediaRequestModifyInfo

type ConstVarType struct {
    Name  string      `json:"name"`
    Value interface{} `json:"value"`
}

type CallDagRunConfigType struct {
    ServerType int            `json:"server_type"`
    Appid      string         `json:"appid"`
    LBType     string         `json:"lb_type"`
    LBName     string         `json:"lb_name"`
    Filiter    string         `json:"filiter"`
    ConstVar   []ConstVarType `json:"const_var"`
}

func main() {

    jsonstr := `{"dataSetId":2001,"fieldInfos":{"duration":{"id":80079,"value":"59"},"om_level":{"id":2409,"value":"4"}},"id":"g0936lt1u0f","modifyFieldInfos":{"om_level":{"id":2409,"new":"4","old":""}},"timeStamp":1584599734}`
    var t MediaRequestModifyInfo
    err := gjson.DecodeTo(jsonstr, &t)
    fmt.Println(err)
    fmt.Println(gjson.New(t).MustToJsonString())
}
5

实验了一下,如果按照我的想法改,那么就不能处理结构体中继承的变量。 有什么办法区分吗

9

我看看

8

@zmcity 确实有点问题,我来处理一下哈,需要花点时间。

1

我试了一下这里替换成如下代码可以达到效果,不过不知道是否会引入其他问题

tmp:=doMapConvert(rvField.Interface(), recursive, tags...)
kinda := reflect.TypeOf(rvField.Interface()).Name()
if  kinda != fieldName {
    m[name] = tmp
}else{
    for k, v := range tmp {
        m[k] = v
    }
}
1

@zmcity 不好意思,这里有个转换函数调用错了,改成这样就好了,虽然我时长会review自己之前的代码,虽然我平时写代码比较仔细,但是难免会有一些小细节会产生疏漏。GF框架实现了非常强大便捷的gconv类型转换模块,内部代码和设计十分精妙,是不需要修改的。我再完善一下单元测试再提交代码哈。 image

7

@zmcity 已经提交到master分支,可以更新下再试试。

2

测试可用了,是否可以打个tag方便我使用go mod 引用?