在 Go 中解组时键入检查 json 值

7rh*_*vnn 2 json go

我正在使用一个通常提供 json 字符串值的 API,但它们有时会提供数字。例如,99% 的时间是这样的:

{
    "Description": "Doorknob",
    "Amount": "3.25"
}
Run Code Online (Sandbox Code Playgroud)

但无论出于何种原因,有时是这样的:

{
    "Description": "Lightbulb",
    "Amount": 4.70
}
Run Code Online (Sandbox Code Playgroud)

这是我正在使用的结构,它在 99% 的时间里都有效:

type Cart struct {
    Description string `json:"Description"`
    Amount      string `json:"Amount"`
}
Run Code Online (Sandbox Code Playgroud)

但是当他们提供数字金额时它会中断。解组结构时进行类型检查的最佳方法是什么?

游乐场:https : //play.golang.org/p/S_gp2sQC5-A

icz*_*cza 5

对于一般情况,您可以interface{}按照Burak Serdar's answer 中的描述使用。

特别是对于数字,有json.Number类型:它接受 JSON 数字和 JSON 字符串,如果它以字符串形式给出,它可以“自动”解析Number.Int64()Number.Float64()。不需要自定义封送拆收器/解封器。

type Cart struct {
    Description string      `json:"Description"`
    Amount      json.Number `json:"Amount"`
}
Run Code Online (Sandbox Code Playgroud)

测试它:

var (
    cart1 = []byte(`{
    "Description": "Doorknob",
    "Amount": "3.25"
}`)

    cart2 = []byte(`{
    "Description": "Lightbulb",
    "Amount": 4.70
}`)
)

func main() {
    var c1, c2 Cart
    if err := json.Unmarshal(cart1, &c1); err != nil {
        panic(err)
    }
    fmt.Printf("%+v\n", c1)
    if err := json.Unmarshal(cart2, &c2); err != nil {
        panic(err)
    }
    fmt.Printf("%+v\n", c2)
}
Run Code Online (Sandbox Code Playgroud)

输出(在Go Playground上试试):

{Description:Doorknob Amount:3.25}
{Description:Lightbulb Amount:4.70}
Run Code Online (Sandbox Code Playgroud)