为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
BIG阳 2022-01-10 14:53:59
我正在使用 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"` }我是否必须编写另一个结构来处理数组?
查看完整描述

1 回答

?
jeck猫

TA贡献1909条经验 获得超7个赞

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

}


查看完整回答
反对 回复 2022-01-10
  • 1 回答
  • 0 关注
  • 307 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信