【发布时间】:2020-12-23 15:35:55
【问题描述】:
我正在调用一个外部 API,并将其解组为一个结构。
在响应中,大多数字段都是整数,但由于它是 json,因此有几种极端情况可以返回字符串,但仍然是有效/有用的信息: "NaN" , "N/A"
我的结构是这样的:
type Example struct {
Field1 *int64 `json:"field_1,omitempty"`
Field2 *int64 `json:"field_2,omitempty"`
Field3 *int64 `json:"field_3,omitempty"`
}
我们有几个要求:
-
如果 api 返回 NaN 或 N/A 我应该在 FE 中向我的用户显示一个错误,所以我想在“捕捉”错误的同时用 null 替换这些值 这就是我选择指针值的原因。
-
如果没有返回值,则在重新编组时完全省略该值。
为了做到这一点,我试图用 JSON null 替换“NaN”值
b = bytes.Replace(b, []byte("NaN"), []byte("null"), -1) `
但它不起作用,因为"null" 不等于null,这是第 1 个问题。
第二个问题是 omitempty 在重新编组时也不区分 nil、0 和空值。
所以重新编组也失败了。我知道这是 go that is being fixed 中的“常见”问题,但现在有解决办法吗?
因为如果我为“N/A”和“NaN”传递 nil 并使用 omitempty 它将删除它们。如果我通过 0 它将没有意义(商业明智,因为 0 具有“未初始化”以外的含义),如果我删除 Omitempty 它将具有 整个结构每次都编组(大量不必要的数据)并且无法区分 nil(NA / NaN)和 nil(无价值)。
最后一个选项是像这样构建自定义类型和编组/解组器:
type JSONint64 struct {
value *int64
error string
}
但这需要我每次都检查我的 json 响应中的每个数字,而事实上 NaN 和 N/A 是非常罕见的情况,并在前端增加了“复杂性”。
我假设这是一个常见问题,因为 JSON 是无类型的,这通常是如何解决的?
【问题讨论】:
-
或者你可以解组到一个接口,然后检查值是否为整数
-
但这会迫使我每次都为每个字段(有很多)断言,并且我认为会大大降低性能
-
使用自定义解组器到底有什么问题? 是什么意思,这需要我每次都检查我的 json 响应中的每个数字“?由于您使用的是指针,您仍然必须检查它们是否有
nil,并在您想对它们做一些有用的事情时取消引用它们,例如数学。还是我错过了什么? -
是的,目前还不清楚。我的意思是,为了验证我正在接收有效数据,我必须对我收到的所有值运行类型断言函数,而不是自然地将它们解组为 *int64 类型并处理少数边缘情况(如果有)错误。我从来没有收到 null 只是将它发送回我的前端,这是问题的第二部分,在 Go 中很难区分 nil 值和指针的空值。
标签: json go marshalling unmarshalling