将json解组到反射结构
是否可以在不硬编码原始类型的情况下将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
主程序包
进口(
“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 toEmployee
。但是如果我不知道类型呢
当我仅使用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{}。它与非结构类型一致+它适用于该作业。