这是我需要的示意图:
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
获取struct以将其传递给 json.Unmarshal
函数 .
How this decode function will be used?
我有不同结构的多个请求 . 我可以确定我应该使用什么结构来解码请求 . 我在请求类型和结构之间进行映射,如 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.
Solution
感谢@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)
...
相关链接:
1 回答
使用以下代码创建草稿结构的副本并对其进行解组:
playground example