当给定的JSON值不是JSON对象时,解组自定义结构

当给定的JSON值不是JSON对象时,解组自定义结构,json,go,Json,Go,我定义了一个自定义结构,用于将API响应解组到其中。有时,当对象为空或丢失时,API决定发送空字符串(“”)。我不清楚如何处理这种类型的不匹配。实际上,我有数百个这样的自定义结构(嵌套),如果它是空的,API将为最顶层的父级执行此操作。如果有某种方法可以在不需要自定义UnmarshalJSON方法的情况下全局执行此操作,那将是理想的。我正在使用代码生成,因此可以轻松添加这些方法 当我第一次尝试编写自己的自定义解组JSON时,我遇到了一个循环: func(e MyStruct)解组JSON(b[]

我定义了一个自定义结构,用于将API响应解组到其中。有时,当对象为空或丢失时,API决定发送空字符串(
“”
)。我不清楚如何处理这种类型的不匹配。实际上,我有数百个这样的自定义结构(嵌套),如果它是空的,API将为最顶层的父级执行此操作。如果有某种方法可以在不需要自定义
UnmarshalJSON
方法的情况下全局执行此操作,那将是理想的。我正在使用代码生成,因此可以轻松添加这些方法

当我第一次尝试编写自己的自定义
解组JSON
时,我遇到了一个循环:

func(e MyStruct)解组JSON(b[]字节)错误{
t:=MyStruct{}
如果字符串(b)=````{e=t}else{
如果err:=json.Unmarshal(b,e);err!=nil{
返回fmt.Errorf(“未能分析嵌套结构:%v”,错误)
}
}
归零
}
我明白为什么我最终陷入了循环,但我有一种感觉,我错过了一个更好的解决方案

我在围棋场上做了一个例子


如果要查找更多上下文,我当前生成的代码就在这里:

使用以下代码来解组值

var emptyString = []byte(`""`)

func (e *MyStruct) UnmarshalJSON(b []byte) error {
    if bytes.Equal(b, emptyString) {
        *e = MyStruct{}
        return nil
    }
    type t MyStruct
    if err := json.Unmarshal(b, (*t)(e)); err != nil {
        return fmt.Errorf("failed to parse nested structure: %w", err)
    }
    return nil
}
注:

  • UnmarshalJSON
    必须位于指针接收器上
  • 通过声明与
    MyStruct
    具有相同底层类型的新类型
    t
    来避免递归。解组为类型为
    t
    的值
  • 比较字节而不是字符串以避免分配
  • 允许使用错误。与调用方一样,使用%w作为错误的格式动词

那里的字体转换非常优雅!删除我的,赞成这个解决方案。