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