以下是我需要的示意图:
func decode(data []byte, target interface{}) (interface{}, error) {
decoded := target.(reflect.TypeOf(target)) // pseudocode
err := json.Unmarshal(data, &decoded)
...
我在SO上发现了几个类似的问题,但所有解决方案都是关于target.(type)
的转换。这不是我寻找的最佳解决方案。
我也找到了带反射的解决方案:
decoded := reflect.ValueOf(target).Convert(reflect.TypeOf(target))
// fmt.Printf("%T", decoded) == reflect.Value
但我无法理解如何从reflect.Value
获取结构以将其传递给json.Unmarshal
函数。
如何使用此decode
功能?
我在不同的结构中有多个请求。我可以确定应该使用什么结构来解码请求。我在请求类型和结构之间进行映射,如map[RequestMethod]interface{}
。
原理图版本如下所示:
func hydrate(data []byte) (interface{}, error) {
var base baseResponse
if err := json.Unmarshal(data, &base); err != nil {
return nil, err
}
target, ok := methodsMap[Method(base.Method)]
if !ok {
return nil, errors.New("Trying to hydrate data with unknown method: " + base.Method)
}
decoded, err := decode(data, target) // Expected target type.
添加了:
如果我们将target
传递给json.Unmarshal
而不转换为类型,我们将获得map
。例如:
func decode(data []byte, target interface{}) (interface{}, error) {
err := json.Unmarshal(data, &target)
// fmt.Printf("%T", target) == map[string]interface{} not struct.
解决方案
感谢@icza我们找到了解决方案:
func hydrate(data [] byte)(interface {},error){ var base baseResponse
if err := json.Unmarshal(data, &base); err != nil {
return nil, err
}
target, ok := methodsMap[Method(base.Method)]
if !ok {
return nil, errors.New("Trying to hydrate data with unknown method: " + base.Method)
}
// Clone request draft struct.
decoded := reflect.New(reflect.ValueOf(target).Type()).Interface()
err := decode(data, decoded)
...
相关链接:
答案 0 :(得分:4)
使用以下代码创建草稿结构的副本并对其进行解组:
t := reflect.TypeOf(methodsMap[Method(base.Method)])
pv := reflect.New(t)
err := json.Unmarshal(p, pv.Interface())
return pv.Elem().Interface(), err // pv.Elem() dereferences ptr