如何定义将包含许多其他不同类型的泛型类型
How to define a generic types that will hold many other diferent types
问题的一些背景:
我们正在使用 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"`
}
P.S:我们愿意接受不同的建议,以更好地解决这个问题,如果需要,我们还可以添加更多信息。
您可以使用 fat 接口:
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
}
问题的一些背景:
我们正在使用 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"`
}
P.S:我们愿意接受不同的建议,以更好地解决这个问题,如果需要,我们还可以添加更多信息。
您可以使用 fat 接口:
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
}