在golang json.Unmarshal中处理单个或数组结构的好方法是什么?

我正在使用 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)?


我的结构看起来像:


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"`

 }

我是否必须编写另一个结构来处理数组?


BIG阳
浏览 308回答 1
1回答

jeck猫

使用UnmarshalJSON()覆盖控制解组过程。https://play.golang.org/p/pCSgymQYC3package mainimport (    "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)}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go