如何定义可容纳许多其他不同类型的泛型类型

发布于 2025-01-09 11:56:27 字数 918 浏览 1 评论 0原文

问题的一些背景:

我们正在使用 golang 在 aws 中创建一个 lambda 函数,在这个函数中我们需要使用 graphql 从数据库中检索一些信息。

我们能够这样做,但目前在将响应解析为有效类型时遇到一些问题,因为我们希望使用单一类型来保存所有可能的场景。

为了更好地解释这一点,请查看“示例”,然后查看“目标”。

示例:

我们将收到类似这样的内容:

{
  "data": {
    "getUser": {
      "id": "example1",
      "name": "example_name"
    }
  }
}

以及类似的内容(以及更多):

{
  "data": {
    "getEvent": {
        "id": "event1",
        "name": "example_name"
      }
    }
  }
}

目标:

因此,我们想要创建的是一种表示“数据”字段的类型,并且它也可以具有多种表示形式,如下所示:

type Response {
  Data <???> `json:"data"`
}

其中 是一个类型,可以是同一类型的“getUser”和“getEvent”(以及许多其他不同类型):

type GetPerson {
  Id string `json:"id"`
  Name string `json:"name"`
}

type GetEvent {
  Id string `json:"id"`
  Name string `json:"name"`
}

PS:我们愿意接受不同的建议,以更好地解决此问题,如果需要,我们还可以添加更多信息。

Some context to the problem:

We are creating a lambda function in aws with golang and in this function we need to retrieve some information from our database using graphql.

We were able to do so but we are currently facing some issues when parsing the response into a valid type because we wanted to use a single type to hold all possible scenarios.

To better explain this, look into "Examples" and then see the "Goal".

Examples:

We will be receiving something like this:

{
  "data": {
    "getUser": {
      "id": "example1",
      "name": "example_name"
    }
  }
}

and like this (and many more):

{
  "data": {
    "getEvent": {
        "id": "event1",
        "name": "example_name"
      }
    }
  }
}

Goal:

So, what we wanted to create was a type that represented the "data" field and that it could also have multiple representations, like this:

type Response {
  Data <???> `json:"data"`
}

Where the is a type that can be, at the same type, a "getUser" and a "getEvent" (and many more different types):

type GetPerson {
  Id string `json:"id"`
  Name string `json:"name"`
}

type GetEvent {
  Id string `json:"id"`
  Name string `json:"name"`
}

P.S: We are open to different suggestions as to better approach this issue and if needed, we can also add more information.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

您可以使用胖接口

type Data struct {
   Person *GetPerson `json:"user"`
   Event *GetEvent `json:"event"`
   ...
}

然后,解组Data的一个实例,查看包含的元素中哪一个不为nil,然后使用它。

您还可以实现多态接口。下面是这个想法的草图:

type Data struct {
  Item interface{}
}

type dataMarshal struct {
   Item map[string]json.RawMessage
}

// Map JSON keys to factory functions
var factory:=map[string]func()interface{} {
   "user": func() interface{} { return &GetUser{} },
   "event": func() interface{} {return &GetEvent{} },
}

func (d *Data) UnmarshalJSON(in []byte) error {
  var data dataMarshal
  // Unmarshal data with key and raw message
  err:=json.Unmarshal(in,&data)
  for k,v:=range data.Item {
     // Based on the key, create a new object
     obj:=factory[k]()
      // Unmarshal new object
     err:=json.Unmarshal(v,obj)
     d.Item=obj
  }
  return nil
}

You can use a fat interface:

type Data struct {
   Person *GetPerson `json:"user"`
   Event *GetEvent `json:"event"`
   ...
}

Then, unmarshal an instance of Data, see which one of the included elements is not nil, and use that.

You can also implement a polymorphic interface. Below is the sketch of the idea:

type Data struct {
  Item interface{}
}

type dataMarshal struct {
   Item map[string]json.RawMessage
}

// Map JSON keys to factory functions
var factory:=map[string]func()interface{} {
   "user": func() interface{} { return &GetUser{} },
   "event": func() interface{} {return &GetEvent{} },
}

func (d *Data) UnmarshalJSON(in []byte) error {
  var data dataMarshal
  // Unmarshal data with key and raw message
  err:=json.Unmarshal(in,&data)
  for k,v:=range data.Item {
     // Based on the key, create a new object
     obj:=factory[k]()
      // Unmarshal new object
     err:=json.Unmarshal(v,obj)
     d.Item=obj
  }
  return nil
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文