本文介绍了在golang json.Unmarshal中处理单个或数组结构的好方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!



问题是如何在不写另一个结构的情况下在数组和单个结构之间切换。我不知道如何用文字解释。
这里是一个例子:

从雅虎获取一个符号报价看起来像这样:

  { 查询:{ 计数:1, 创建: 2016-05-11T02:12:33Z, 朗: 的en-US, 结果 :{quote:{Change:+ 0.21,DaysLow:9.32,DaysHigh:9.68,Name:Alcoa Inc.普通股,开放:9.56 ,PreviousClose:9.46,Symbol:aa,Volume:22266533,PercentChange:+ 2.22%}}}} 



从Yahoo API获取多个引用:

  { 查询:{ 计数:2, 创造: 2016-05-11T02:17:48Z, 郎: EN-US, 结果:{ 报价:[{更改:+ 0.21,DaysLow:9.32,DaysHigh:9.68,名称:Alcoa Inc.普通股,开放:9.56,PreviousClose:9.46 , 符号: AA, 卷: 22266533, PercentChange: + 2.22%},{ 更改: + 0.63, DaysLow: 92.11, DaysHigh: 93.57,Name:Apple Inc.,Open:93.35,PreviousClose:92.79,Symbol:aapl,Volume:33686836,PercentChange + 0.68%}]}}} 

区别在于quote变成数组 []



使用 json.Unmarshal时如何处理(quoteResultRawJSON,& queryResult)



结构看起来像:

 类型QueryResult结构{
Id bson.ObjectId`bson:_ id,omitempty`
Query query`json:query`
}

类型查询结构{
计数int`json:count`
创建的字符串`json:创建的``
Lang字符串`json:lang`
结果引用`json:结果`
}

类型引用struct {
Quote StockQuote`json:quote`//这里是区别。为了处理[]
}

类型StockQuote struct {
更改字符串`json:change`
,我需要重写整个结构吗? PercentChange字符串`json:percentChange`
DaysLow字符串`json:daysLow`
DaysHigh字符串`json:daysHigh`
打开字符串`json:open`
PreviousClose string`json:previousClose``
符号字符串`json:符号`
名称字符串`json:name`
卷字符串`json:volume
}

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

解决方案

使用 UnmarshalJSON()覆盖来控制解组过程。 b



  package main 

import(
log
encoding / json
bytes


const(
s1 =`{query:{count:1,created: 05-11T 02:12:33Z 郎: EN-US, 结果:{ 报价:{ 改变: + 0.21, DaysLow: 9.32, DaysHigh: 9.68 ,名称:Alcoa Inc.普通股票,公开: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股票, 开放: 9.56, PreviousClose: 9.46, 符号: AA, 音量: 22266533, PercentChange: + 2.22%},{ 更改 :+ 0.63,DaysLow:92.11,DaysHigh:93.57,Name:Apple Inc。,Open:93.35,PreviousClose:92.79 :aapl,Volume:33686836,PercentChange:+ 0.68%}]}}}`

QueryResult struct {
// Id bson .ObjectId`bson:_id,omitempty`
Query query`json:query`
}

类型查询结构{
Count int`json: count`
创建的字符串`json:创建的``
Lang字符串`json:lang`
结果引用`json:结果`
}

类型structOrArray结构{
父类型*引用
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 {
加载structOrArray`json:quote`//这里是区别。我是否需要重写整个结构以处理[]
}
类型引用结构{
引用* StockQuote
引用[] StockQuote
}
func(this * Quote)UnmarshalJSON(data [] byte)error {
fq:= fakeQuote {}
if err:= json.Unmarshal(data,& fq); err!=无{
返回错误
}
this.Quote =& fq.Load.s
this.Quotes = fq.Load.a
return nil

类型StockQuote结构{
更改字符串`json:更改``
PercentChange字符串`json:percentChange`
DaysLow字符串`json:daysLow`
DaysHigh string`json:daysHigh`
打开字符串`json:open`
PreviousClose字符串`json:previousClose`
符号字符串`json:symbol `
名称字符串`json:name`
卷字符串`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)
}


I am building a stock quote web app by using Go and Yahoo API.

The question is how to switch between array and single struct without writing another struct. I am not sure how to explain it in words.Here is the example:

Get one symbol quote from Yahoo API looks like this:

{"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%"}}}}

Get multiple quotes from 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%"}]}}}

The difference is the quote becomes an array [].

How to handle it when using json.Unmarshal(quoteResultRawJSON, &queryResult)?

I have struct look like:

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

Do I have to write another struct to handle array?

解决方案

control the unmarshal process with UnmarshalJSON() override.

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)
}

这篇关于在golang json.Unmarshal中处理单个或数组结构的好方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-07 16:57