我得到了一个JSON,格式如下:
{
"Filter": {
"Filters": [
{
"Filter": {
"someKey": "someValue1",
},
"FilterType": "trait"
},
{
"Filter": {
"someKey": "someValue2",
},
"FilterType": "trait"
}
]
},
"FilterType": "and" // this can be an or too
}
每一个过滤器都有一个类型Map到我在代码中得到的一个特定的结构体,正如你所看到的,这有一个递归的特性:滤波器可以是具有多个子滤波器的and
(其也可以是and
或or
等)。
所以,根据类型的不同,我需要递归地将它Map到正确的结构体。有什么建议吗?我考虑过使用mapstructure,但即使这样代码也会变得相当糟糕。
请注意,本示例仅使用and
和trait
过滤器,但假设存在更多类似or
的过滤器
2条答案
按热度按时间l0oc07j21#
这种类型的多态JSON很常见,而且通常不容易处理。我在这里解释的是一种使用单独的结构体来处理它的方法,该结构体仅用于封送,并依赖于后处理来构造过滤器。
您可以定义一个
FilterMarshal
结构,其中包含筛选器的所有可能字段:这个实现假设不存在名称冲突。例如,如果一个过滤器类型有
Filter
字段作为一个类型,而另一个类型有Filter
字段作为不兼容的类型,这将不起作用,您必须使用其他方法。当您在
FilterMarshal
中解组JSON时,您将得到一个与输入JSON匹配的对象树,然后,您可以构造实际的过滤器结构:eh57zj3b2#
在没有明确的特性规范的情况下,您需要使用这个结构体来表示与您在问题中发布的JSON相近的内容。
在Go语言中,过滤器的初始化过程如下
当过滤器被封送为JSON并被漂亮地打印出来时,它们看起来像这样
上面的JSON与您问题中的JSON不完全匹配;它缺少顶层的
Filter
字段,我认为我在这个答案中提出的结构体将简化实现和心理模型。在https://go.dev/play/p/6cLPT28DG2O的GoPlayground给予一下
如果您确实需要匹配问题中的JSON
下面是您需要的结构体
它是这样填充的
在https://go.dev/play/p/uB_LmJc6NGH的Go Playground中试用