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

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

当我第一次尝试编写自己的 custom 时UnmarshalJSON,我最终陷入了一个循环:

func (e MyStruct) UnmarshalJSON(b []byte) error {
    t := MyStruct{}
    if string(b) == `""` {e = t} else {
        if err := json.Unmarshal(b, e); err != nil {
            return fmt.Errorf("failed to parse nested structure: %v", err)
        }
    }
    return nil
}

我明白为什么我最终陷入了循环,但我觉得我缺少更好的解决方案。

我在 Go Playground 中创建了一个示例。

https://play.golang.org/p/DrrFhA3TzPv

如果您正在寻找更多上下文,我当前生成的代码在这里:https : //github.com/mbrancato/edgeos/blob/a8af9143aa82ddece27089bf2f543f473c97d2db/sdk/config.go

回答

使用以下代码解组值。

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 必须在指针接收器上。
  • 通过声明tMyStruct. 解组为类型的值t
  • 比较字节而不是字符串以避免分配。
  • 允许使用错误。在调用者中,使用 %w 作为错误的格式动词。
  • Very elegant type conversion there! Deleting mine in favour of this solution.

以上是当给定的JSON值不是JSON对象时解组自定义结构的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>