我在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{}
答案 0 :(得分:8)
当您拨打以下电话时:
st := reflect.ValueOf(n)
ValueOf
传递PlaceNode
结构的副本。因此,对st
所做的任何更改都不会在n
中看到。因此,包将此类情况视为不可寻址的值。如果您想要reflect.Value
代表n
,请尝试使用以下内容:
st := reflect.ValueOf(&n).Elem()
现在st
直接使用n
而不是副本,并且可以寻址。您现在应该可以在其及其字段上使用各种Set*
方法。