【问题标题】:Unmarshaling unnamed JSON array of unnamed objects解组未命名对象的未命名 JSON 数组
【发布时间】:2014-03-06 08:24:26
【问题描述】:

我试图用 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)

Here 是您可以运行以尝试解决问题的示例代码:

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

【问题讨论】:

    标签: json go


    【解决方案1】:

    在这一行:

    tradeResult := new(TradesResult)
    

    您正在使用*TradeResult 类型声明tradeResult 变量。即,指向切片的指针。您收到的错误是因为您不能在指向切片的指针上使用索引表示法。

    解决此问题的一种方法是将最后一行更改为使用(*tradeResult)[0].Amount。或者,您可以将tradeResult 声明为:

    var tradeResult TradeResult
    

    json 模块将能够很好地解码为 &tradeResult,并且您无需取消引用它即可索引到切片中。

    【讨论】:

    • 你不能也把new改成make吗?
    • 非常感谢。我可能太困了。 ://
    • 我想出了同样的答案,但我不确定原因。感谢您的解释!文档在这个解释上似乎有点模棱两可golang.org/doc/effective_go.html#allocation_new 特别是Values of type SyncedBuffer are also ready to use immediately upon allocation or just declaration. In the next snippet, both p and v will work correctly without further arrangement.
    • @Jeff: make(TradeResult, 0) 也可以。但这相当于零初始化切片,因此只需声明变量即可得到相同的结果。
    猜你喜欢
    • 2020-03-02
    • 1970-01-01
    • 2018-05-03
    • 2018-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-20
    相关资源
    最近更新 更多