Go Unmarshal reflect.Type got map [string] interface {}

时间:2017-09-08 08:43:07

标签: json go

我想将json字符串转换为某个结构,用作func param
  我用反射得到Param Type,这个工作正常,
  但如果我使用json.Unmarshal,我总是会map[string]interface{}

这是一个迷你运行示例,文件名为json_test.go

package testJson

import (
    "reflect"
    "encoding/json"
    "testing"
    "log"
)

type LoginForm struct {
    Name string
}

func Login(login LoginForm) {

}

func TestRun(t *testing.T) {
    _func := Login
    f := reflect.ValueOf(_func)
    funcType := f.Type()
    paramType := funcType.In(0)
    log.Print(paramType.Name())
    v := reflect.New(paramType).Elem().Interface()
    jsonstr := `{"Name":"123"}`
    log.Print(jsonstr)
    log.Print(reflect.TypeOf(v).Name())
    log.Print("%+v", v)
    err := json.Unmarshal([]byte(jsonstr), &v)
    if err != nil {
        panic(err)
    }
    log.Print(reflect.TypeOf(v).Name())
    log.Print( v)
    var in []reflect.Value
    in = make([]reflect.Value, funcType.NumIn())
    in[0] = reflect.ValueOf(v)
    f.Call(in)
}

感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

不要reflect.New指针类型,因为它的结果是指向指针的指针,而不是reflect.New指针类型的Elem

改变这个:

v := reflect.New(paramType).Elem().Interface()

对此:

v := reflect.New(paramType.Elem()).Interface()

此时v已经是指向LoginForm的指针,因此在转到&时,您无需使用Unmarshal获取其地址。

https://play.golang.org/p/JM4fRXb7fo

你获得map[string]interface{}的原因也是因为Interface()方法的返回类型不足为奇interface{},所以虽然v的基础类型可能是它的任何东西“最顶层”类型是interface{}。那么,执行&v会得到*interface{}而不是有意*LoginForm。在docs中,您可以发现尝试将JSON对象解组为interface{}将导致值为map[string]interface{}的值。