为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
富国沪深 2022-06-27 16:43:05
我正在使用通常提供 json 字符串值的 API,但它们有时会提供数字。例如,99% 的时间是这样的:{    "Description": "Doorknob",    "Amount": "3.25"}但无论出于何种原因,有时它是这样的:{    "Description": "Lightbulb",    "Amount": 4.70}这是我正在使用的结构,它在 99% 的时间内都有效:type Cart struct {    Description string `json:"Description"`    Amount      string `json:"Amount"`}但是当他们提供数字量时它会中断。解组结构时类型检查的最佳方法是什么?操场: https: //play.golang.org/p/S_gp2sQC5-A
查看完整描述

2 回答

?
开心每一天1111

TA贡献1836条经验 获得超13个赞

对于一般情况,您可以interface{}按照Burak Serdar 的回答中所述使用。


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


type Cart struct {

    Description string      `json:"Description"`

    Amount      json.Number `json:"Amount"`

}

测试它:


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)

}

输出(在Go Playground上试试):


{Description:Doorknob Amount:3.25}

{Description:Lightbulb Amount:4.70}


查看完整回答
反对 回复 2022-06-27
?
www说

TA贡献1775条经验 获得超8个赞

如果该字段可以是字符串或 int,则可以使用 interface{},然后找出底层值:


type Cart struct {

    Description string `json:"Description"`

    Amount      interface{} `json:"Amount"`

}


func (c Cart) GetAmount() (float64,error) {

  if d, ok:=c.Amount.(float64); ok {

     return d,nil

  }

  if s, ok:=c.Amount.(string); ok {

     return strconv.ParseFloat(s,64)

  }

  return 0, errors.New("Invalid amount")

}


查看完整回答
反对 回复 2022-06-27
  • 2 回答
  • 0 关注
  • 120 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信