我有多个
struct
。我的主要响应结构称为 WsPayload
,它有一个名为 Payload
的成员变量。 Payload
可以是我的 Earthquake
结构或 EventReport
结构。
我的问题:我如何定义我的
WsPayload
Payload 成员变量,以便它可以接受我的两个结构?我可以在 Go 中使用动态变量来完成此任务吗?
我正在构建一个从客户端接收有效负载(JSON 格式)的 websocket。然后我将该消息广播到 websocket 客户端(JSON 格式)。在有效负载中,有一个名为
Etype
的结构体成员,它确定有效负载的类型。它可能是事件或地震有效负载。
type WsPayload struct {
Action string `json: "action"`
Message string `json: "message"`
Etype string `json: "etype"`
Payload EventReport `json: "payload"`. //<---
Conn WebSocketConnection `json: "-"`
}
type Earthquake struct {
Body string `json: "body"`
Location string `json: "location"`
Rate int `json: "rate_earthquake"`
Date string `json: "lat"`
Time string `json: "lng"`
}
type EventReport struct {
Title string `json: "title"`
Body string `json: "body"`
Date string `json: "date"`
Time string `json: "time"`
Type string `json: "type"`
Id string `json: "id"`
Photo []string `json: "photo"`
}
目前,我一次只能在我的
struct
中定义一个 WsPayload
。
将该字段声明为类型 any。
type WsPayload struct {
Action string `json:"action"`
Message string `json:"message"`
Etype string `json:"etype"`
Payload any `json:"payload"`
}
任何类型的值都可以分配给该字段并进行编组:
v := WsPayload{
Message: "msg",
Etype: "report",
Payload: EventReport{Title: "title"},
}
b, err := json.Marshal(v)
if err != nil { /* handle error */ }
// b is {"action":"","message":"msg","etype":"report","payload":{"title":"title","body":"","date":"","time":"","type":"","id":"","photo":null}}
要解组 JSON,请使用 json.RawMessage 作为变体字段:
var v WsPayload
u := struct {
*WsPayload
Payload json.RawMessage `json:"payload"`
}{
&v,
nil,
}
if err := json.Unmarshal(b, &u); err != nil {
/* handle error */
}
打开 Etype 字段以解组变体部分:
switch u.Etype {
case "report":
var r EventReport
if err := json.Unmarshal(u.Payload, &r); err != nil {
log.Fatal(err)
}
v.Payload = r
// handle other types here...
default:
log.Fatalf("type %s not handled", u.Etype)
}
输出是可变的
v
。