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

时间:2014-08-30 01:20:25

标签: go

我在Go map[string]interface{}中解组JSON并使用界面的混合字符串,float和slice值来填充PlaceNode结构的字段值。

我需要类似"默认值"因为并非所有JSON对象都具有所有Struct字段。来自其他语言背景,Structs是可索引的我习惯做这样的事情来设置n Placenode变量的值(例如,好像它是self或{{1} JavaScript中的关键字)。

this

相反,我在n[key] = value; 结构上有一个方法来读取PlaceNode,使用interface{}并可选择分配值(如果可以设置字段)。我的reflect没有实现所有值,因此我无法直接在我的结构中进行拼写。

显然没有一个字段通过此interfaces{}检查。所以我一定是要做错了。

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

s.CanSet()

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{},如下所示:

map[string]interface{}

1 个答案:

答案 0 :(得分:8)

当您拨打以下电话时:

st := reflect.ValueOf(n)

ValueOf传递PlaceNode结构的副本。因此,对st所做的任何更改都不会在n中看到。因此,包将此类情况视为不可寻址的值。如果您想要reflect.Value代表n,请尝试使用以下内容:

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

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