gpt4 book ai didi

json - 包含接口(interface)列表的结构上的 UnmarshalJSON

转载 作者:IT王子 更新时间:2023-10-29 02:29:14 25 4
gpt4 key购买 nike

我想 UnmarshalJSON 包含如下接口(interface)的结构:

type Filterer interface {
Filter(s string) error
}

type FieldFilter struct {
Key string
Val string
}

func (ff *FieldFilter) Filter(s string) error {
// Do something
}

type Test struct {
Name string
Filters []Filterer
}

我的想法是像这样发送一个 json:

{
"Name": "testing",
"Filters": [
{
"FieldFilter": {
"Key": "key",
"Val": "val"
}
}
]
}

但是,当将此 json 发送到解码器时,返回以下异常:json: cannot unmarshal object into Go struct field Test.Filters of type Filterer

我完全理解这个问题,但不知道如何明智地处理这个问题。在 go 中寻找解决此问题的惯用方法的建议。

最佳答案

根据我自己的问题,我研究了如何为接口(interface)列表实现 UnmarshalJSON。最终,这让我发表了一篇关于如何正确执行此操作的博文。基本上有 2 个主要解决方案:

  1. 将所需的 JSON 字符串解析为 map[string]*json.RawMessage 并从那里开始工作。
  2. 为接口(interface)列表创建一个别名并为该别名实现 UnmarshalJSON。但是,您仍然需要使用 map[string]*json.RawMessage 和一些手动工作。一切都是有代价的!

我强烈建议采用秒方法。虽然这两种解决方案可能会产生相同数量的代码行,但利用类型别名并减少对 json.RawMessage 类型的依赖将使代码更易于管理,尤其是在需要在 UnmarshalJSON 实现上支持多个接口(interface)

要直接回答这个问题,首先要为接口(interface)列表创建一个类型别名:

type Filterers []Filterer

现在继续实现 JSON 的解码:

func (f *Filterers) UnmarshalJSON(b []byte) error {
var FilterFields map[string]*json.RawMessage
if err := json.Unmarshal(b, &FilterFields); err != nil {
return err
}
for LFKey, LFValue := range FilterFields {
if LFKey == "FieldFilter" {
var MyFieldFilters []*json.RawMessage
if err := json.Unmarshal(*LFValue, &MyFieldFilters); err != nil {
return err
}
for _, MyFieldFilter := range MyFieldFilters {
var filter FieldFilter
if err := json.Unmarshal(*MyFieldFilter, &filter); err != nil {
return err
}
*f = append(*f, &filter)
}
}
}
return nil
}

第二种方法的详细解释(包括一些示例和完整的工作代码片段)可用 on my own blog

关于json - 包含接口(interface)列表的结构上的 UnmarshalJSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44826376/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com