问题描述
问题是如何在不写另一个结构的情况下在数组和单个结构之间切换。我不知道如何用文字解释。
这里是一个例子:
从雅虎获取一个符号报价看起来像这样:
{ 查询:{ 计数:1, 创建: 2016-05-11T02:12:33Z, 朗: 的en-US, 结果 :{quote:{Change:+ 0.21,DaysLow:9.32,DaysHigh:9.68,Name:Alcoa Inc.普通股,开放:9.56 ,PreviousClose:9.46,Symbol:aa,Volume:22266533,PercentChange:+ 2.22%}}}}
从Yahoo API获取多个引用:
{ 查询:{ 计数:2, 创造: 2016-05-11T02:17:48Z, 郎: EN-US, 结果:{ 报价:[{更改:+ 0.21,DaysLow:9.32,DaysHigh:9.68,名称:Alcoa Inc.普通股,开放:9.56,PreviousClose:9.46 , 符号: AA, 卷: 22266533, PercentChange: + 2.22%},{ 更改: + 0.63, DaysLow: 92.11, DaysHigh: 93.57,Name:Apple Inc.,Open:93.35,PreviousClose:92.79,Symbol:aapl,Volume:33686836,PercentChange + 0.68%}]}}}
区别在于quote变成数组
[]
。
使用
json.Unmarshal时如何处理(quoteResultRawJSON,& queryResult)
?
结构看起来像:
类型QueryResult结构{
Id bson.ObjectId`bson:_ id,omitempty`
Query query`json:query`
}
类型查询结构{
计数int`json:count`
创建的字符串`json:创建的``
Lang字符串`json:lang`
结果引用`json:结果`
}
类型引用struct {
Quote StockQuote`json:quote`//这里是区别。为了处理[]
}
类型StockQuote struct {
更改字符串`json:change`
,我需要重写整个结构吗? PercentChange字符串`json:percentChange`
DaysLow字符串`json:daysLow`
DaysHigh字符串`json:daysHigh`
打开字符串`json:open`
PreviousClose string`json:previousClose``
符号字符串`json:符号`
名称字符串`json:name`
卷字符串`json:volume
}
我必须编写另一个结构来处理数组吗?
解决方案使用
UnmarshalJSON()
覆盖来控制解组过程。 b
package main
import(
log
encoding / json
bytes
)
const(
s1 =`{query:{count:1,created: 05-11T 02:12:33Z 郎: EN-US, 结果:{ 报价:{ 改变: + 0.21, DaysLow: 9.32, DaysHigh: 9.68 ,名称:Alcoa Inc.普通股票,公开:9.56,PreviousClose:9.46,Symbol:aa,Volume:22266533,PercentChange +2.22%}}}}`
s2 =`{query:{count:2,created:2016-05-11T02:17:48Z,lang: en-us,results:{quote:[{Change:+ 0.21,DaysLow:9.32,DaysHigh:9.68,Name股票, 开放: 9.56, PreviousClose: 9.46, 符号: AA, 音量: 22266533, PercentChange: + 2.22%},{ 更改 :+ 0.63,DaysLow:92.11,DaysHigh:93.57,Name:Apple Inc。,Open:93.35,PreviousClose:92.79 :aapl,Volume:33686836,PercentChange:+ 0.68%}]}}}`
)
QueryResult struct {
// Id bson .ObjectId`bson:_id,omitempty`
Query query`json:query`
}
类型查询结构{
Count int`json: count`
创建的字符串`json:创建的``
Lang字符串`json:lang`
结果引用`json:结果`
}
类型structOrArray结构{
父类型*引用
s StockQuote
a [] StockQuote
}
func(this * structOrArray)UnmarshalJSON(data [] byte)error {
d:= json.NewDecoder(bytes.NewBuffer(data))
t,err:= d.Token();
if err!= nil {
return err
}
if t == json.Delim('['){
if err:= json.Unmarshal( data,& this.a); err!= nil {
return err
}
return nil
}
if err:= json.Unmarshal(data, & this.s); err!= nil {
return err
}
return nil
}
type fakeQuote struct {
加载structOrArray`json:quote`//这里是区别。我是否需要重写整个结构以处理[]
}
类型引用结构{
引用* StockQuote
引用[] StockQuote
}
func(this * Quote)UnmarshalJSON(data [] byte)error {
fq:= fakeQuote {}
if err:= json.Unmarshal(data,& fq); err!=无{
返回错误
}
this.Quote =& fq.Load.s
this.Quotes = fq.Load.a
return nil
类型StockQuote结构{
更改字符串`json:更改``
PercentChange字符串`json:percentChange`
DaysLow字符串`json:daysLow`
DaysHigh string`json:daysHigh`
打开字符串`json:open`
PreviousClose字符串`json:previousClose`
符号字符串`json:symbol `
名称字符串`json:name`
卷字符串`json:volume`
}
func main(){
r:= QueryResult {}
err:= json.Unmarshal([] byte(s1),& r)
if err!= nil {
log.Fatalln(err)
}
log.Println(r.Query.Results.Quote)
log.Println(r.Query.Results.Quotes)
err = json.Unmarshal ([] byte(s2),& r)
if err!= nil {
log.Fatalln(err)
}
log.Println(r.Query.Results .Quote)
log.Println(r.Query.Results.Quotes)
}
I am building a stock quote web app by using Go and Yahoo API.
The question is how to switch between array and single struct without writing another struct. I am not sure how to explain it in words.Here is the example:
Get one symbol quote from Yahoo API looks like this:
{"query":{"count":1,"created":"2016-05-11T02:12:33Z","lang":"en-US","results":{"quote":{"Change":"+0.21","DaysLow":"9.32","DaysHigh":"9.68","Name":"Alcoa Inc. Common Stock","Open":"9.56","PreviousClose":"9.46","Symbol":"aa","Volume":"22266533","PercentChange":"+2.22%"}}}}
Get multiple quotes from Yahoo API:
{"query":{"count":2,"created":"2016-05-11T02:17:48Z","lang":"en-us","results":{"quote":[{"Change":"+0.21","DaysLow":"9.32","DaysHigh":"9.68","Name":"Alcoa Inc. Common Stock","Open":"9.56","PreviousClose":"9.46","Symbol":"aa","Volume":"22266533","PercentChange":"+2.22%"},{"Change":"+0.63","DaysLow":"92.11","DaysHigh":"93.57","Name":"Apple Inc.","Open":"93.35","PreviousClose":"92.79","Symbol":"aapl","Volume":"33686836","PercentChange":"+0.68%"}]}}}
The difference is the quote becomes an array
[]
.How to handle it when using
json.Unmarshal(quoteResultRawJSON, &queryResult)
?I have struct look like:
type QueryResult struct { Id bson.ObjectId `bson:"_id,omitempty"` Query Query `json:"query"` } type Query struct { Count int `json:"count"` Created string `json:"created"` Lang string `json:"lang"` Results Quote `json:"results"` } type Quote struct { Quote StockQuote `json:"quote"` //Here is the difference. Do I need to re-write the whole struct in order to handle [] } type StockQuote struct { Change string `json:"change"` PercentChange string `json:"percentChange"` DaysLow string `json:"daysLow"` DaysHigh string `json:"daysHigh"` Open string `json:"open"` PreviousClose string `json:"previousClose"` Symbol string `json:"symbol"` Name string `json:"name"` Volume string `json:"volume"` }
Do I have to write another struct to handle array?
解决方案control the unmarshal process with
UnmarshalJSON()
override.https://play.golang.org/p/pCSgymQYC3
package main import ( "log" "encoding/json" "bytes" ) const( s1=`{"query":{"count":1,"created":"2016-05-11T02:12:33Z","lang":"en-US","results":{"quote":{"Change":"+0.21","DaysLow":"9.32","DaysHigh":"9.68","Name":"Alcoa Inc. Common Stock","Open":"9.56","PreviousClose":"9.46","Symbol":"aa","Volume":"22266533","PercentChange":"+2.22%"}}}}` s2=`{"query":{"count":2,"created":"2016-05-11T02:17:48Z","lang":"en-us","results":{"quote":[{"Change":"+0.21","DaysLow":"9.32","DaysHigh":"9.68","Name":"Alcoa Inc. Common Stock","Open":"9.56","PreviousClose":"9.46","Symbol":"aa","Volume":"22266533","PercentChange":"+2.22%"},{"Change":"+0.63","DaysLow":"92.11","DaysHigh":"93.57","Name":"Apple Inc.","Open":"93.35","PreviousClose":"92.79","Symbol":"aapl","Volume":"33686836","PercentChange":"+0.68%"}]}}}` ) type QueryResult struct { //Id bson.ObjectId `bson:"_id,omitempty"` Query Query `json:"query"` } type Query struct { Count int `json:"count"` Created string `json:"created"` Lang string `json:"lang"` Results Quote `json:"results"` } type structOrArray struct{ parent *Quote s StockQuote a []StockQuote } func (this *structOrArray)UnmarshalJSON(data []byte) error{ d := json.NewDecoder(bytes.NewBuffer(data)) t, err := d.Token(); if err != nil{ return err } if t==json.Delim('['){ if err := json.Unmarshal(data, &this.a);err != nil { return err } return nil } if err := json.Unmarshal(data, &this.s);err != nil { return err } return nil } type fakeQuote struct{ Load structOrArray `json:"quote"` //Here is the difference. Do I need to re-write the whole struct in order to handle [] } type Quote struct { Quote *StockQuote Quotes []StockQuote } func (this *Quote)UnmarshalJSON(data []byte) error{ fq := fakeQuote{} if err := json.Unmarshal(data, &fq);err != nil{ return err } this.Quote = &fq.Load.s this.Quotes = fq.Load.a return nil } type StockQuote struct { Change string `json:"change"` PercentChange string `json:"percentChange"` DaysLow string `json:"daysLow"` DaysHigh string `json:"daysHigh"` Open string `json:"open"` PreviousClose string `json:"previousClose"` Symbol string `json:"symbol"` Name string `json:"name"` Volume string `json:"volume"` } func main() { r := QueryResult{} err := json.Unmarshal([]byte(s1), &r) if err != nil { log.Fatalln(err) } log.Println(r.Query.Results.Quote) log.Println(r.Query.Results.Quotes) err = json.Unmarshal([]byte(s2), &r) if err != nil { log.Fatalln(err) } log.Println(r.Query.Results.Quote) log.Println(r.Query.Results.Quotes) }
这篇关于在golang json.Unmarshal中处理单个或数组结构的好方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!