【问题标题】:Go Unmarshal reflect.Type got map[string]interface{}Go Unmarshal reflect.Type 得到了 map[string]interface{}
【发布时间】:2017-09-08 17:37:23
【问题描述】:

我想将 json 字符串转换为一些结构,用作 func 参数
我使用反射来获取参数类型,这很好,
但是如果我使用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)
}

感谢您的帮助!

【问题讨论】:

  • 您必须显示所有相关代码。请展示一个可运行的最小示例。
  • 添加可运行的例子,谢谢

标签: json go


【解决方案1】:

不要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{},而不是inteded *LoginForm。在docs 中,您会发现尝试将JSON 对象解组为interface{} 将导致map[string]interface{} 类型的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-08
    • 2015-01-14
    • 2014-09-25
    • 2016-08-06
    • 2018-08-05
    • 2021-05-26
    • 2021-06-11
    相关资源
    最近更新 更多