2016-05-11 3 views
0

Я создаю веб-приложение для котировки акций, используя API Go и Yahoo.Что такое хороший способ обработки одиночной или массивной структуры в golang json.Unmarshal?

Вопрос заключается в том, как переключаться между массивом и отдельной структурой без написания другой структуры. Я не знаю, как объяснить это словами. Вот пример:

Получить один символ цитаты из 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"` 
} 

Должен ли я написать еще одну-структуру для обработки массива?

ответ

-1

контроль над процессом без маршала с 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) 
}