英文:
Unmarshaling string encoded json ints with nulls uses previous value when null
问题
我正在尝试解析包含以字符串编码的整数的 JSON 数据。使用标签来指定字段以字符串编码的方式是有效的,但是当字段为 null 时,我遇到了问题。主要问题似乎是 null 值没有被编码为字符串,因此解析器会忽略它并继续解析。问题在于它以某种原因将先前解码的值混入其中。
你有什么想法,我如何正确解析这个问题?
以下是我的代码:
package main
import (
"encoding/json"
"log"
)
type Product struct {
Price int `json:",string,omitempty"`
}
func main() {
data := `
[
{"price": "1"},
{"price": null},
{"price": "2"}
]
`
var products []Product
if err := json.Unmarshal([]byte(data), &products); err != nil {
log.Printf("%#v", err)
}
log.Printf("%#v", products)
}
输出结果:
[]main.Product{main.Product{Price:1}, main.Product{Price:1}, main.Product{Price:2}}
英文:
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:
package main
import (
"encoding/json"
"log"
)
type Product struct {
Price int `json:",string,omitempty"`
}
func main() {
data := `
[
{"price": "1"},
{"price": null},
{"price": "2"}
]
`
var products []Product
if err := json.Unmarshal([]byte(data), &products); err != nil {
log.Printf("%#v", err)
}
log.Printf("%#v", products)
}
Output:
[]main.Product{main.Product{Price:1}, main.Product{Price:1}, main.Product{Price:2}}
答案1
得分: 2
感觉像是json包中的一个错误。
你可以通过自定义的解码器来解决这个问题,像这样,尽管如果你有一个复杂的结构体可能会有些麻烦:
func (p *Product) UnmarshalJSON(b []byte) error {
m := map[string]string{}
err := json.Unmarshal(b, &m)
if err != nil {
return err
}
if priceStr, ok := m["price"]; ok {
p.Price, _ = strconv.Atoi(priceStr)
}
return nil
}
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:
func (p *Product) UnmarshalJSON(b []byte) error {
m := map[string]string{}
err := json.Unmarshal(b, &m)
if err != nil {
return err
}
if priceStr, ok := m["price"]; ok {
p.Price, _ = strconv.Atoi(priceStr)
}
return nil
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论