解码包含空值的字符串编码的 JSON 整数时,会使用先前的值。

huangapple go评论107阅读模式
英文:

Unmarshaling string encoded json ints with nulls uses previous value when null

问题

我正在尝试解析包含以字符串编码的整数的 JSON 数据。使用标签来指定字段以字符串编码的方式是有效的,但是当字段为 null 时,我遇到了问题。主要问题似乎是 null 值没有被编码为字符串,因此解析器会忽略它并继续解析。问题在于它以某种原因将先前解码的值混入其中。

你有什么想法,我如何正确解析这个问题?

以下是我的代码:

  1. package main
  2. import (
  3. "encoding/json"
  4. "log"
  5. )
  6. type Product struct {
  7. Price int `json:",string,omitempty"`
  8. }
  9. func main() {
  10. data := `
  11. [
  12. {"price": "1"},
  13. {"price": null},
  14. {"price": "2"}
  15. ]
  16. `
  17. var products []Product
  18. if err := json.Unmarshal([]byte(data), &products); err != nil {
  19. log.Printf("%#v", err)
  20. }
  21. log.Printf("%#v", products)
  22. }

输出结果:

  1. []main.Product{main.Product{Price:1}, main.Product{Price:1}, main.Product{Price:2}}

在 Go Playground 上运行代码

英文:

I am trying to unmarshal json that contains ints encoded as strings. Using tags to specify that the field is encoded as a string works, but I am running into issues when the field is null. The main problem, it seems, is that the null is not encoded as a string so the parser ignores it and keeps going. The problem is that it jams in the previously decoded value for some reason.

Any ideas on how I can get this parsing correctly?

I have the following code:

  1. package main
  2. import (
  3. "encoding/json"
  4. "log"
  5. )
  6. type Product struct {
  7. Price int `json:",string,omitempty"`
  8. }
  9. func main() {
  10. data := `
  11. [
  12. {"price": "1"},
  13. {"price": null},
  14. {"price": "2"}
  15. ]
  16. `
  17. var products []Product
  18. if err := json.Unmarshal([]byte(data), &products); err != nil {
  19. log.Printf("%#v", err)
  20. }
  21. log.Printf("%#v", products)
  22. }

Output:

  1. []main.Product{main.Product{Price:1}, main.Product{Price:1}, main.Product{Price:2}}

Code on go playground

答案1

得分: 2

感觉像是json包中的一个错误。

你可以通过自定义的解码器来解决这个问题,像这样,尽管如果你有一个复杂的结构体可能会有些麻烦:

  1. func (p *Product) UnmarshalJSON(b []byte) error {
  2. m := map[string]string{}
  3. err := json.Unmarshal(b, &m)
  4. if err != nil {
  5. return err
  6. }
  7. if priceStr, ok := m["price"]; ok {
  8. p.Price, _ = strconv.Atoi(priceStr)
  9. }
  10. return nil
  11. }

http://play.golang.org/p/UKjfVqHCGi

英文:

Feels like a bug in the json package.

You can work around it with a custom Unmarshaller, like this, although it may be annoying if you've got a complex struct:

  1. func (p *Product) UnmarshalJSON(b []byte) error {
  2. m := map[string]string{}
  3. err := json.Unmarshal(b, &m)
  4. if err != nil {
  5. return err
  6. }
  7. if priceStr, ok := m["price"]; ok {
  8. p.Price, _ = strconv.Atoi(priceStr)
  9. }
  10. return nil
  11. }

http://play.golang.org/p/UKjfVqHCGi

huangapple
  • 本文由 发表于 2013年12月30日 13:29:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/20833847.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定