【发布时间】:2021-08-06 15:36:31
【问题描述】:
我在一个模块中有以下结构:
type Event struct {
Name string `json:"name"`
Version string `json:"version"`
Payload interface{} `json:"payload"`
}
目标是,我可以接受任意结构为Payload,并使用json.Marshal 和一些消息服务将Event 类型的最终结构作为json 序列化字符串发送。
但是,当我在另一个项目中尝试 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 正确的结构类型?
【问题讨论】:
-
Event.Payload中的值对于 JSON 对象将是map[string]interface{}类型,对于 JSON 数组将是[]interface{}。您不能将其强制转换或类型断言为任何其他类型。您只能从interface{}值中键入断言struct如果它确实包含该类型的值。类型断言不会转换值,也不会神奇地创建新值。 -
Unmarshal不会创建基于 JSON 的类型。它解组为你给它的类型。您是否希望在接收端解组任何有效负载?为什么不将Unmarshal直接输入正确的类型? -
@super 不是说我必须复制
Event-struct 的原始代码,只是为Payload-field 使用不同的类型?我的目标是使Event尽可能通用并重用我之前编写的代码。 -
作为一般评论:我不认为这个问题那么糟糕!很抱歉,如果这个问题表明我对 Go 缺乏了解。
-
@TimHilt 在
Marshal方面,它可以保持通用,但如果您希望将 json 转换为正确的类型,则需要将这部分代码拆分并使用不同的结构每种Payload,是的。
标签: go struct interface casting type-conversion