5

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 Answer 1

5

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.

Sign up to request clarification or add additional context in comments.

4 Comments

can't you also just change new to make?
Thanks, seriously. I may be too sleepy. :/
I figured this same answer out but I wasn't sure of the reason. Thanks for this explanation! The docs seem a bit ambiguous on this explanation golang.org/doc/effective_go.html#allocation_new Specifically 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) would also work. But that's equivalent to a zero initialised slice, so just declaring the variable gives the same result.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.