将json解组到反射结构

将json解组到反射结构,json,go,reflection,unmarshalling,Json,Go,Reflection,Unmarshalling,是否可以在不硬编码原始类型的情况下将JSON解组到由反射生成的结构中 主程序包 进口( “fmt” “编码/json” “反映” ) 类型Employee结构{ Firstname字符串`json:“Firstname”` } func main(){ //原始结构 来源:=新员工 t:=反射类型(原始) v:=reflect.New(t.Elem()) //反射结构 新:=v.Elem().Interface()(雇员) //反汇编到反射结构 Unmarshal([]字节(“{\“firstn

是否可以在不硬编码原始类型的情况下将JSON解组到由反射生成的结构中

主程序包
进口(
“fmt”
“编码/json”
“反映”
)
类型Employee结构{
Firstname字符串`json:“Firstname”`
}
func main(){
//原始结构
来源:=新员工
t:=反射类型(原始)
v:=reflect.New(t.Elem())
//反射结构
新:=v.Elem().Interface()(雇员)
//反汇编到反射结构
Unmarshal([]字节(“{\“firstname\”:“bender\”),&new)
fmt.Printf(“%+v\n”,新)
}
在本例中,我使用了一个cast to
Employee
。但是如果我不知道类型呢

当我仅使用
v
进行反建模时,结构将归零

json.Unmarshal([]byte("{\"firstname\": \"bender\"}"), v)
当我省略演员阵容时,我得到了一张地图。这是可以理解的

json.Unmarshal([]byte("{\"firstname\": \"bender\"}"), v.Elem().Interface())

这里的问题是,如果在这里省略类型断言:

new := v.Elem().Interface()
new
被推断为具有
接口{}
类型

然后,当您将地址移到解组时,
&new
的类型是
*接口{}
(指向接口{}的指针),并且解组无法按预期工作

如果直接使用指针引用而不是获取
Elem()
,则可以避免类型断言

func main() {
  //Original struct
  orig := new(Employee)

  t := reflect.TypeOf(orig)
  v := reflect.New(t.Elem())

  // reflected pointer
  newP := v.Interface()

  // Unmarshal to reflected struct pointer
  json.Unmarshal([]byte("{\"firstname\": \"bender\"}"), newP)

  fmt.Printf("%+v\n", newP)
}

操场:

如果您根本不知道类型,可以将JSON字符串解组到接口{}中。如果随后需要处理未编组的数据,可以将其转换为所需的类型

下面是一个例子:

package main

import (
    "encoding/json"
    "fmt"
    "reflect"
    "unsafe"
)

type Employee struct {
    Firstname string `json:"firstName"`
}

func deserialize(jsonData string) interface{} {
    var obj interface{}

    if err := json.Unmarshal([]byte(jsonData), &obj); err != nil {
        panic(err)
    }

    return obj
}

func NewEmployee(objData map[string]interface{}) *Employee {
    s := (*Employee)(nil)
    t := reflect.TypeOf(s).Elem()
    employeePtr := reflect.New(t)
    employee := (*Employee)(unsafe.Pointer(employeePtr.Pointer()))
    employee.Firstname = objData["firstName"].(string)

    return employee
}

func main() {
    jsonData := "{\"firstName\": \"John\"}"

    obj := deserialize(jsonData)

    objData := obj.(map[string]interface{})
    employee := NewEmployee(objData)

    fmt.Printf("%s\n", employee.Firstname)
}

您可以在上查看它。

因为它确实伤害了我的眼睛:为什么有一个名为
new
的变量?与更灵活的
&Employee{}
相比,您使用
new(Employee)
有什么意义?new(Something)优于&Something{}。它与非结构类型一致+它适用于该作业。