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

我在 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

   }

 }


慕田峪7331174
浏览 406回答 1
1回答

杨魅力

当您拨打以下电话时:st := reflect.ValueOf(n)ValueOf传递了PlaceNode结构的副本。因此,对 所做的任何更改st都不会在n. 出于这个原因,包将这种情况视为不可寻址的值。如果你想要一个reflect.Value代表n,尝试使用这样的东西:st := reflect.ValueOf(&n).Elem()现在st是直接使用n而不是副本,并且是可寻址的。您现在应该能够Set*对它及其字段使用各种方法。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go