英文:
Go: unexpected end of JSON input and json.Unmarshal returns nil values
问题
我正在测试如何解析我正在使用的API的JSON响应。
JSON的格式大致如下:
body := []byte(`[
{"name":"Name1", "value":100.00},
{"name":"Name2", "value":200.00}
]`)
我已经搜索了各种方法来实现这个,但是无法使其工作。解析返回了零值。我还收到了一个错误消息"unexpected end of JSON input"(在示例中我已经删除了错误处理)。
完整的代码示例可以在这里找到:https://play.golang.org/p/VMdWuAm6HS
参考链接:
- https://godoc.org/encoding/json#RawMessage
- https://stackoverflow.com/questions/27994327/golang-json-unmarshal-unexpected-end-of-json-input
- https://stackoverflow.com/questions/28254102/how-to-unmarshal-json-into-interface-in-golang
英文:
I'm testing out how to unmarshal a json response from an API I'm using.
The json looks something like the following;
body := []byte(`[
{"name":"Name1", "value":100.00},
{"name":"Name2", "value":200.00}
]`)
I've searched around for various ways to do this, but fail to get this to work. The unmarshal returns zero values. I also get an error "unexpected end of JSON input" (I've removed the error handling in the example).
Full code example - https://play.golang.org/p/VMdWuAm6HS
Reference:
答案1
得分: 2
你的输入JSON可以使用简单的[]Obj
进行建模,其中Obj
是你的类型:
type Obj struct {
Name string `json:"name"`
Value float32 `json:"value"`
}
实际上不需要其他内容:
body := []byte(`[
{"name":"Name1", "value":100.00},
{"name":"Name2", "value":200.00}]`)
var res []Obj
err := json.Unmarshal(body, &res)
fmt.Printf("%#v\n%v\n", res, err)
输出包含来自输入JSON的数据(在Go Playground上尝试一下):
[]main.Obj{main.Obj{Name:"Name1", Value:100}, main.Obj{Name:"Name2", Value:200}}
<nil>
回到你的代码:
你的问题在于你使用了这个模型:
type Obj struct {
Name string `json:"name"`
Value float32 `json:"value"`
}
type Result struct {
Data json.RawMessage
}
var res []Result
但是这个res
变量将对应以下JSON:
[
{"Data":{"name":"Name1", "value":100.00}},
{"Data":{"name":"Name2", "value":200.00}}
]
我想你可以看到区别:这里的数组元素是带有"Data"
字段的JSON对象,然后使用你的Obj
进行建模。你可以使用你原来的解析代码正确解析这个输入JSON,在Go Playground上尝试一下:
[{{"name":"Name1", "value":100.00}} {{"name":"Name2", "value":200.00}}]
&main.Obj{Name:"Name1", Value:100}
&main.Obj{Name:"Name2", Value:200}
英文:
Your input JSON can be modeled with a simple []Obj
where Obj
is your type:
type Obj struct {
Name string `json:"name"`
Value float32 `json:"value"`
}
Nothing else is required, really:
body := []byte(`[
{"name":"Name1", "value":100.00},
{"name":"Name2", "value":200.00}]`)
var res []Obj
err := json.Unmarshal(body, &res)
fmt.Printf("%#v\n%v\n", res, err)
Output contains the data from the input JSON (try it on the Go Playground):
[]main.Obj{main.Obj{Name:"Name1", Value:100}, main.Obj{Name:"Name2", Value:200}}
<nil>
Back to your code:
Where you're going wrong is that you use this model:
type Obj struct {
Name string `json:"name"`
Value float32 `json:"value"`
}
type Result struct {
Data json.RawMessage
}
var res []Result
But this res
variable would model the following JSON:
[
{"Data":{"name":"Name1", "value":100.00}},
{"Data":{"name":"Name2", "value":200.00}}
]
I think you can see the difference: the elements of the array here are JSON Objects with a "Data"
field, which then are modeled with your Obj
. This input JSON is then properly parsed with your original parsing code, you can try it on the Go Playground:
[{{"name":"Name1", "value":100.00}} {{"name":"Name2", "value":200.00}}]
&main.Obj{Name:"Name1", Value:100}
&main.Obj{Name:"Name2", Value:200}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论