我正在调用一个外部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"`
}
我们有几项要求:
为此,我尝试将"NaN“值替换为JSON null
do
b = bytes.Replace(b, []byte("NaN"), []byte("null"), -1) `
但是它不能工作,因为"null"
不等于null
,这是第一个问题。
第二个问题是,在再婚时,省略也没有区分0、0和空值。
所以再婚也失败了。我知道在go 正在修理中中这是一个“常见”的问题,但是现在有工作要做吗?
因为如果我将“N/A”和"NaN“的零传递给空,它就会删除它们。如果我传递0,它就没有意义(从业务上讲,0除了“未初始化”之外还有其他含义),如果我删除Omitempty,它将在每次(大量不必要的数据)中对整个结构进行整理,并且无法区分nil ( NA / NaN )和nil (无值)。
最后一个选项是构建一个自定义类型和马歇尔/解封组器,如下所示:
type JSONint64 struct {
value *int64
error string
}
但这将要求我检查json响应中的每个数字,每次,实际上,NaN和N/A是非常罕见的,并且在前端增加了“复杂性”。
我假设这是一个常见的问题,因为JSON是非类型化的,这通常是如何解决的?
发布于 2020-09-04 03:59:10
我会将法警转换为map[string]interface{}
值,然后使用反射或类型断言来计算值的数据类型。
解组将其中一个存储在接口值中:
bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null
就像这样:
package main
import (
"encoding/json"
"fmt"
)
type Example struct {
Field1 *int64 `json:"field_1,omitempty"`
Field2 *int64 `json:"field_2,omitempty"`
Field3 *int64 `json:"field_3,omitempty"`
}
func typeof(v interface{}) string {
switch v.(type) {
case float64:
return "float64"
case string:
return "string"
default:
return "unknown"
}
}
func main() {
d := []byte(`{"field_1": "n/a", "field_2": 2 }"`)
e := make(map[string]interface{})
err := json.Unmarshal(d, &e)
if err != nil {
fmt.Printf("%v\n", err)
}
fmt.Printf("%+v\n", e)
example := Example{}
for k, v := range e {
switch typeof(v) {
case "float64":
val := int64(v.(float64))
switch k {
case "field_1":
example.Field1 = &val
case "field_2":
example.Field2 = &val
case "field_3":
example.Field3 = &val
default:
fmt.Printf("Unexpected field: %v\n", k)
}
default:
// display error
}
}
fmt.Printf("Example field_2: %d\n", *example.Field2)
}
https://stackoverflow.com/questions/63739872
复制