使用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)

}