我正在使用Go和Yahoo API构建股票报价网络应用。
问题是如何在数组和单个结构之间切换而无需编写另一个结构。我不确定如何用语言解释它。这是示例:
从Yahoo API获得一个符号引号如下所示:
{"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%"}}}}
从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%"}]}}}
不同之处在于引号成为一个数组[]。
[]
使用时如何处理json.Unmarshal(quoteResultRawJSON, &queryResult)?
json.Unmarshal(quoteResultRawJSON, &queryResult)
我的结构看起来像:
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"` }
我是否需要编写另一个结构来处理数组?
通过UnmarshalJSON()覆盖控制解组过程。
UnmarshalJSON()
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) }