首页 > 解决方案 > 用于 JSON 编组的嵌套 Go 结构和可选结构

问题描述

我正在尝试初始化一个嵌套结构,然后编组为 json 以获取 API 响应。我遇到的挑战是组件之一(一个结构切片)可以有 n 个成员,但是是两种可能类型(文本、图像)中的一种。

我要创建的 JSON 如下所示:

{
  "messages": [
    {
      "message_parts": [
        {
          "text": {
            "content": "dfdffd"
          }
        },
        {
          "image": {
            "url": "https://image.jpg"
          }
        }
      ],
      "actor_id": "44444444",
      "actor_type": "agent"
    }
  ],
  "channel_id": "44444444",
  "users": [
    {
      "id": "44444444"
    }
  ]
}

在 message_parts 切片中,它可以包含至少一个文本或图像,但可能每个都包含一个。

我的结构目前看起来像这样:

   Type messagePayload struct {
        Messages  []Messages `json:"messages"`
        Status    string     `json:"status,omitempty"`
        ChannelID string     `json:"channel_id"`
        Users     []Users    `json:"users"`
    }
    type Messages struct {
        MessageParts []MessageParts `json:"message_parts"`
        ActorID      string         `json:"actor_id"`
        ActorType    string         `json:"actor_type"`
    }

    type Users struct {
        ID string `json:"id"`
    }
    type Text struct {
        Content string `json:"content,omitempty"`
    }
    type MessageParts struct {
        Text  *Text  `json:"text,omitempty"`
        Image *Image `json:"image,omitempty"`
    }
    type Image struct {
        URL string `json:"url,omitempty"`
    }

如果它们不存在,我真的很难以一种不会出现在 json 中的方式来初始化它。

这就是我所在的位置,但它显然不起作用:

payload := &messagePayload{
    Messages: []Messages{
        {
            MessageParts: []MessageParts{
                {
                    &Text{
                        Content: text,
                    },
                },
                {
                    &Image{
                        URL: mediaurl,
                    },
                },
            },
            ActorID:   agentID,
            ActorType: "agent",
        }},
    ChannelID: channelid,
    Users: []Users{
        {
            ID: user,
        },
    },
}

编辑:感谢下面的提示和其他一些发现,我发现最好的方法是初始化有效负载,然后根据需要添加文本和图像的切片:https: //play.golang.org/p/Pmmv00spcI6

标签: jsongostruct

解决方案


如上所述,我找到了一个解决方案——您需要在没有文本或图像数据的情况下初始化有效负载,然后将它们附加到 MessageParts 切片:

package main

import (
    "encoding/json"
    "fmt"
)

type messagePayload struct {
    Messages  []Messages `json:"messages"`
    Status    string     `json:"status,omitempty"`
    ChannelID string     `json:"channel_id"`
    Users     []Users    `json:"users"`
}
type Messages struct {
    MessageParts []MessageParts `json:"message_parts"`
    ActorID      string         `json:"actor_id"`
    ActorType    string         `json:"actor_type"`
}

type Users struct {
    ID string `json:"id"`
}
type Text struct {
    Content string `json:"content,omitempty"`
}
type MessageParts struct {
    Text  *Text  `json:"text,omitempty"`
    Image *Image `json:"image,omitempty"`
}
type Image struct {
    URL string `json:"url,omitempty"`
}

func main() {

    payload := &messagePayload{
        Messages: []Messages{
            {
                MessageParts: []MessageParts{

                },
                ActorID:   "id",
                ActorType: "agent",
            }},
        ChannelID: "cid",
        Users: []Users{
            {
                ID: "user1",
            },
        },
    }
    var text= new(MessageParts)
    text.Text = &Text{Content: "LOL"}
        var image = new(MessageParts)
        image.Image= &Image{URL: "https://"}
    payload.Messages[0].MessageParts = append(payload.Messages[0].MessageParts, *text)
    payload.Messages[0].MessageParts = append(payload.Messages[0].MessageParts, *image)
    m, err := json.Marshal(payload)
    if err != nil {
        fmt.Println("Error, ", err)
        return
    }
    fmt.Println(string(m))
}

推荐阅读