将接口{}转换为结构
Cast interface{} to struct
我在一个模块中有以下结构:
type Event struct {
Name string `json:"name"`
Version string `json:"version"`
Payload interface{} `json:"payload"`
}
目标是,我可以接受任意结构作为 Payload
并将类型 Event
的最终结构作为 json 序列化字符串发送,使用 json.Marshal
和一些消息服务。
但是,当我尝试在另一个项目中json.Unmarshal
时,我无法访问Event.Payload
内部的字段,因为Go显然不知道它的最终类型。
我试过用这样的东西:
type EventPayload struct{
Name string `json:"name"`
}
// ...
event := &events.Event{}
event.Payload = &EventPayload{}
if err := json.Unmarshal(msg.Data, event); err != nil {
return err
}
event.Payload.Name // Won't work: "type interface{} has no field or method Status"
然而,Go 仍然认为 event.Payload
是一个 interface{}
。
在这种情况下,我如何告诉 Go 正确的结构类型?
How can I tell Go the correct struct-type in this case?
你不能。这不是 encoding/json.Unmarshal 的工作方式。您要么必须解组为正确的类型或其他类型,要么使用 json.Raw 消息并进行第二次解组或诸如此类的事情,但是您采用的方法根本行不通。
您完全可以按照您的描述进行操作,您只需要使用类型断言来获取基础类型即可。 json.Unmarshal
,提供一个预填充具体类型的 interface{}
字段,将 使用该具体类型。
event := &Event{}
event.Payload = &EventPayload{}
msg := []byte(`{"Name": "foo", "Version": "1", "Payload": {"Name": "bar"}}`)
if err := json.Unmarshal(msg, event); err != nil {
panic(err)
}
pl := event.Payload.(*EventPayload)
fmt.Println(pl.Name)
工作示例(在 playground 中稍微修改为 运行):https://play.golang.org/p/IDXLKeMGw8_1
我在一个模块中有以下结构:
type Event struct {
Name string `json:"name"`
Version string `json:"version"`
Payload interface{} `json:"payload"`
}
目标是,我可以接受任意结构作为 Payload
并将类型 Event
的最终结构作为 json 序列化字符串发送,使用 json.Marshal
和一些消息服务。
但是,当我尝试在另一个项目中json.Unmarshal
时,我无法访问Event.Payload
内部的字段,因为Go显然不知道它的最终类型。
我试过用这样的东西:
type EventPayload struct{
Name string `json:"name"`
}
// ...
event := &events.Event{}
event.Payload = &EventPayload{}
if err := json.Unmarshal(msg.Data, event); err != nil {
return err
}
event.Payload.Name // Won't work: "type interface{} has no field or method Status"
然而,Go 仍然认为 event.Payload
是一个 interface{}
。
在这种情况下,我如何告诉 Go 正确的结构类型?
How can I tell Go the correct struct-type in this case?
你不能。这不是 encoding/json.Unmarshal 的工作方式。您要么必须解组为正确的类型或其他类型,要么使用 json.Raw 消息并进行第二次解组或诸如此类的事情,但是您采用的方法根本行不通。
您完全可以按照您的描述进行操作,您只需要使用类型断言来获取基础类型即可。 json.Unmarshal
,提供一个预填充具体类型的 interface{}
字段,将 使用该具体类型。
event := &Event{}
event.Payload = &EventPayload{}
msg := []byte(`{"Name": "foo", "Version": "1", "Payload": {"Name": "bar"}}`)
if err := json.Unmarshal(msg, event); err != nil {
panic(err)
}
pl := event.Payload.(*EventPayload)
fmt.Println(pl.Name)
工作示例(在 playground 中稍微修改为 运行):https://play.golang.org/p/IDXLKeMGw8_1