Dictionary json解组后转到映射结构类型转换

Dictionary json解组后转到映射结构类型转换,dictionary,go,struct,reflection,types,Dictionary,Go,Struct,Reflection,Types,我试图在围棋中创建一种工厂模式,但没有任何运气。我希望能够像其他语言那样使用反射来动态地创建具有对象名称的对象/结构。然而,go似乎不像我希望的那样支持它,因此我选择了一种更简单的方法(见下文),通过使用映射将结构映射到字符串 我现在遇到的问题是,根据我的测试,它最初似乎可以工作,但是,一旦我对它调用json.Unmarshal,它就会从正确的结构类型变为map[string]接口{},好像它几乎要恢复到包含对象的类型 st := make(map[string]interface{}) st[

我试图在围棋中创建一种工厂模式,但没有任何运气。我希望能够像其他语言那样使用反射来动态地创建具有对象名称的对象/结构。然而,go似乎不像我希望的那样支持它,因此我选择了一种更简单的方法(见下文),通过使用映射将结构映射到字符串

我现在遇到的问题是,根据我的测试,它最初似乎可以工作,但是,一旦我对它调用
json.Unmarshal
,它就会从正确的结构类型变为
map[string]接口{}
,好像它几乎要恢复到包含对象的类型

st := make(map[string]interface{})
st["StructName1"] = s.StructName1{}
st["StructName2"] = s.StructName2{}
//...

fmt.Printf("1) '%+v' '%+v'\n", reflect.ValueOf(st["StructName1"]), reflect.TypeOf(st["StructName1"]))
fmt.Printf("2) '%+v' '%+v'\n", reflect.ValueOf(s.StructName1{}), reflect.TypeOf(s.StructName1{}))

ff := st["StructName1"]
err := json.Unmarshal([]byte(reqBody), &ff)
fmt.Printf("3) '%+v' '%+v'\n", reflect.ValueOf(ff), reflect.TypeOf(ff))
输出:

1) '{V1: V2:{V2v1: V2v2: V2v3:}}' 'structs.StructName1'
2) '{V1: V2:{V2v1: V2v2: V2v3:}}' 'structs.StructName1'

3) 'map[V2:map[V2v1:value1 V2v2:value2 V2v3:value3] V1:"value4"]' 'map[string]interface {}'
解组“成功”,因为它没有错误,但是在3)中打印的类型是
map[string]接口{}
。你知道为什么吗

另外,直接指定结构而不是使用映射,即

ff := s.StructName1{}
工作完全正常

此外,如果您有任何关于更好的方法的建议,我将不胜感激

提前谢谢

“你知道为什么吗?”

存储在接口中的动态类型是不可寻址的,因此正如Cerise Limon指出的那样,
json.Unmarshal
,将退回到将json解码为一种内置类型,一种最适合json数据的类型,例如
map[string]interface{}
,或
[]interface{}
,或
string
,等等


“如果您有任何关于更好的方法的建议,我将不胜感激。”

这取决于你到底想做什么,然而,为了简单地解决你目前的困境,你可以做如下简单的事情:

st := make(map[string]func() interface{})
st["StructName1"] = func() interface{} { return &s.StructName1{} }
st["StructName2"] = func() interface{} { return &s.StructName2{} }

// ...

ff := st["StructName1"]()
err := json.Unmarshal([]byte(reqBody), ff)
fmt.Printf("'%T' '%+v'\n", ff, ff)
“你知道为什么吗?”

存储在接口中的动态类型是不可寻址的,因此正如Cerise Limon指出的那样,
json.Unmarshal
,将退回到将json解码为一种内置类型,一种最适合json数据的类型,例如
map[string]interface{}
,或
[]interface{}
,或
string
,等等


“如果您有任何关于更好的方法的建议,我将不胜感激。”

这取决于你到底想做什么,然而,为了简单地解决你目前的困境,你可以做如下简单的事情:

st := make(map[string]func() interface{})
st["StructName1"] = func() interface{} { return &s.StructName1{} }
st["StructName2"] = func() interface{} { return &s.StructName2{} }

// ...

ff := st["StructName1"]()
err := json.Unmarshal([]byte(reqBody), ff)
fmt.Printf("'%T' '%+v'\n", ff, ff)

解组将使用存储在接口中的动态类型。看见解组忽略
s.StructName1{}
值,因为该值不可寻址。解码器返回到解码到
接口{}
@CeriseLimón Yup,看到您对问题的评论,立即意识到我的错误。解组将使用存储在接口中的动态类型。看见解组忽略
s.StructName1{}
值,因为该值不可寻址。解码器返回到解码到
接口{}
@CeriseLimón是的,看到你对问题的评论,立即意识到我的错误。