解组未命名的 JSON 数组中的未命名对象

huangapple go评论84阅读模式
英文:

Unmarshaling unnamed JSON array of unnamed objects

问题

我正在尝试使用Go进行解组的JSON是一个未命名的未命名对象数组:

[
{
"date": 1394062029,
"price": 654.964,
"amount": 5.61567,
"tid": 31862774,
"price_currency": "USD",
"item": "BTC",
"trade_type": "ask"
},
{
"date": 1394062029,
"price": 654.964,
"amount": 0.3,
"tid": 31862773,
"price_currency": "USD",
"item": "BTC",
"trade_type": "ask"
},
{
"date": 1394062028,
"price": 654.964,
"amount": 0.0193335,
"tid": 31862772,
"price_currency": "USD",
"item": "BTC",
"trade_type": "bid"
}
]

我可以成功解组对象并将完整的tradesResult数组打印为%#v,但是当我尝试访问数组的元素时,我会得到以下错误。

prog.go:41: invalid operation: tradeResult[0] (index of type *TradesResult)

这里是一个你可以运行以尝试解决问题的示例代码:

// You can edit this code!
// Click here and start typing.
package main

import (
"fmt"
"io/ioutil"
"net/http"
"encoding/json"
)

type TradesResultData struct {
Date float64 json:"date"
Price float64 json:"price"
Amount float64 json:"amount"
Trade float64 json:"tid"
Currency string json:"price_currency"
Item string json:"item"
Type string json:"trade_type"
}

type TradesResult []TradesResultData

func main() {
resp, err := http.Get("https://btc-e.com/api/2/btc_usd/trades")
if err != nil {
fmt.Printf("%s\r\n", err)
}
json_response, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("%s\r\n", err)
}
resp.Body.Close()
fmt.Printf("JSON:\r\n%s\r\n", json_response)
tradeResult := new(TradesResult)
err = json.Unmarshal(json_response, &tradeResult)
if err != nil {
fmt.Printf("%s\r\n", err)
}
// Printing trade result first element Amount
fmt.Printf("Element 0 Amount: %v\r\n", tradeResult[0].Amount)
}

英文:

The JSON I am trying to unmarshal with Go is unnamed array of unnamed objects:

[
{
    "date": 1394062029,
    "price": 654.964,
    "amount": 5.61567,
    "tid": 31862774,
    "price_currency": "USD",
    "item": "BTC",
    "trade_type": "ask"
},
{
    "date": 1394062029,
    "price": 654.964,
    "amount": 0.3,
    "tid": 31862773,
    "price_currency": "USD",
    "item": "BTC",
    "trade_type": "ask"
},
{
    "date": 1394062028,
    "price": 654.964,
    "amount": 0.0193335,
    "tid": 31862772,
    "price_currency": "USD",
    "item": "BTC",
    "trade_type": "bid"
}
]

I can successfully unmarshal the object and print the complete tradesResult array as %#v, but when I try to access element of the array I get the following error.

prog.go:41: invalid operation: tradeResult[0] (index of type *TradesResult)

Here is example code you can run to try the problem:

// You can edit this code!
// Click here and start typing.
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"encoding/json"
)

type TradesResultData struct {
	Date     float64 `json:"date"`
	Price    float64 `json:"price"`
	Amount   float64 `json:"amount"`
	Trade    float64 `json:"tid"`
	Currency string  `json:"price_currency"`
	Item     string  `json:"item"`
	Type     string  `json:"trade_type"`
}

type TradesResult []TradesResultData

func main() {
	resp, err := http.Get("https://btc-e.com/api/2/btc_usd/trades")
	if err != nil {
		fmt.Printf("%s\r\n", err)
	}
	json_response, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("%s\r\n", err)
	}
	resp.Body.Close()
	fmt.Printf("JSON:\r\n%s\r\n", json_response)
	tradeResult := new(TradesResult)
	err = json.Unmarshal(json_response, &tradeResult)
	if err != nil {
		fmt.Printf("%s\r\n", err)
	}
	// Printing trade result first element Amount
	fmt.Printf("Element 0 Amount: %v\r\n", tradeResult[0].Amount)
}

答案1

得分: 4

在这行代码中:

tradeResult := new(TradesResult)

你使用了*TradeResult类型声明了tradeResult变量,也就是一个指向切片的指针。你收到的错误是因为你不能在指向切片的指针上使用索引符号。

修复这个问题的一种方法是将最后一行改为使用(*tradeResult)[0].Amount。另外,你也可以将tradeResult声明为:

var tradeResult TradeResult

json模块将能够正常解码为&tradeResult,你就不需要对其进行解引用以索引到切片中的元素。

英文:

On this line:

tradeResult := new(TradesResult)

You are declaring the tradeResult variable using the *TradeResult type. That is, a pointer to a slice. The error you received is because you can't use index notation on a pointer to a slice.

One way to fix this would be to change the last line to use (*tradeResult)[0].Amount. Alternatively, you could declare tradeResult as:

var tradeResult TradeResult

The json module will be able to decode into &tradeResult just fine, and you won't need to dereference it to index into the slice.

huangapple
  • 本文由 发表于 2014年3月6日 08:12:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/22212236.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定