为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 Go 中设置动态结构字段?

如何在 Go 中设置动态结构字段?

Go
慕田峪7331174 2021-08-16 15:13:50
我在 Go to a 中解组 JSON,map[string]interface{}并使用接口的混合字符串、浮点和切片值来填充PlaceNode结构的字段值。我需要诸如“默认值”之类的东西,因为并非所有 JSON 对象都具有所有 Struct 字段。来自其他语言背景,Structs 是否可索引我习惯于做这样的事情来设置n Placenode变量的值(例如,好像它是JavaScript中的 a selforthis关键字)。n[key] = value;相反,如果可以设置字段,我的PlaceNode结构中有一个方法可以读取interface{}、使用reflect和可选地分配一个值。我interfaces{}没有实现所有值,因此我无法直接将其解压缩到我的结构中。显然没有一个字段通过此s.CanSet()检查。所以我一定是在处理这个错误。如何在 Go 中设置动态结构字段?func (n PlaceNode) New(data map[string]interface{}) PlaceNode {    for key, val := range data {        n.Id = key        for k, v := range val.(map[string]interface{}) {            f := reflect.ValueOf(v)            st := reflect.ValueOf(n)            if (st.Kind() == reflect.Struct) {                s := st.FieldByName(k)                if f.Kind() == reflect.String && true == s.CanSet()  {                        s.SetString(f.String());                } else if f.Kind() == reflect.Float64 && true == s.CanSet() {                        s.SetFloat(f.Float());                } else if f.Kind() == reflect.Slice && true == s.CanSet() {                        s.Set(f.Slice(0, f.Len()));                }            }        }    }    return n}该data参数map[string]interface{}有一个也是 a 的接口,map[string]interface{}如下所示:  {   "XV.12A": {    "Area": 1189.132667,    "CensusBlock": 2032,    "CensusBlockGroup": 2,    "CensusCbsaFips": 40900,    "CensusCountyFips": 61,    "CensusMcdFips": 90160,    "CensusMsaFips": 6922,    "CensusPlaceFips": 3204,    "CensusStateFips": 6,    "CensusTract": 203,    "CensusYear": 2010,    "Radius": 19.455402434548,    "RegionSize": 1189.132667   } }
查看完整描述

1 回答

?
杨魅力

TA贡献1811条经验 获得超6个赞

当您拨打以下电话时:

st := reflect.ValueOf(n)

ValueOf传递了PlaceNode结构的副本。因此,对 所做的任何更改st都不会在n. 出于这个原因,包将这种情况视为不可寻址的值。如果你想要一个reflect.Value代表n,尝试使用这样的东西:

st := reflect.ValueOf(&n).Elem()

现在st是直接使用n而不是副本,并且是可寻址的。您现在应该能够Set*对它及其字段使用各种方法。


查看完整回答
反对 回复 2021-08-16
  • 1 回答
  • 0 关注
  • 405 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信