2 回答

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超6個(gè)贊
JSON 是一個(gè)數(shù)組,因此您需要將一個(gè)數(shù)組傳遞給 Decode 方法。還記得檢查返回的錯(cuò)誤。
package main
import(
"encoding/json"
"net/http"
"log"
)
type CoinMarketCapData struct {
Id string
Name string
Symbol string
Rank int
PriceUSD float64
PriceBTC float64
Volume24hUSD float64
MarketCapUSD float64
AvailableSupply float64
TotalSupply float64
PercentChange1h float32
PercentChange24h float32
PercentChange7d float32
}
func getJson(url string, target interface{}) error {
client := &http.Client{}
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Content-Type", "application/json")
r, err := client.Do(req)
if err != nil {
return err
}
defer r.Body.Close()
return json.NewDecoder(r.Body).Decode(target)
}
func main() {
//Test with CoinMarketCap JSON
url2 := "https://api.coinmarketcap.com/v1/ticker/ethereum"
priceData := make([]CoinMarketCapData, 0)
err := getJson(url2, &priceData)
if err != nil {
log.Printf("Failed to decode json: %v", err)
} else {
//Should print "Ethereum Id: ethereum"
log.Printf("Ethereum Id: %v", priceData[0].Id)
}
}
運(yùn)行此打印
2016/08/21 17:15:27 Ethereum Id: ethereum

TA貢獻(xiàn)1799條經(jīng)驗(yàn) 獲得超6個(gè)贊
你是對(duì)的,頂級(jí) API 響應(yīng)類型是一個(gè)列表,它必須反映在解組過程中。解決此問題的一種方法是將您的MarketCap響應(yīng)定義為切片,如下所示:
package main
import (
"encoding/json"
"log"
"net/http"
)
// curl -sLf "https://api.coinmarketcap.com/v1/ticker/ethereum" | JSONGen
// command line helper: `go get github.com/bemasher/JSONGen`
type MarketCapResponse []struct {
AvailableSupply float64 `json:"available_supply"`
HVolumeUsd float64 `json:"24h_volume_usd"`
Id string `json:"id"`
MarketCapUsd float64 `json:"market_cap_usd"`
Name string `json:"name"`
PercentChange1h float64 `json:"percent_change_1h"`
PercentChange24h float64 `json:"percent_change_24h"`
PercentChange7d float64 `json:"percent_change_7d"`
PriceBtc float64 `json:"price_btc"`
PriceUsd float64 `json:"price_usd"`
Rank int64 `json:"rank"`
Symbol string `json:"symbol"`
TotalSupply float64 `json:"total_supply"`
}
然后解組就可以正常工作了。需要注意的一點(diǎn)是指向切片的指針與切片不同。特別是指針不支持索引,這就是為什么需要先取消引用才能訪問列表中的第一項(xiàng)。
func getAndUnmarshal(url string, target interface{}) error {
var client = &http.Client{}
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Content-Type", "application/json")
r, _ := client.Do(req)
defer r.Body.Close()
return json.NewDecoder(r.Body).Decode(target)
}
func main() {
link := "https://api.coinmarketcap.com/v1/ticker/ethereum"
resp := new(MarketCapResponse)
getAndUnmarshal(link, resp)
log.Printf("Ethereum Id: %s", (*resp)[0].Id)
// prints:
// 2016/08/22 02:13:23 Ethereum Id: ethereum
}
另一種方法是為單個(gè)MarketCap定義一個(gè)類型,然后在需要時(shí)創(chuàng)建一個(gè)切片作為目標(biāo):
package main
// curl -sLf "https://api.coinmarketcap.com/v1/ticker/ethereum" | jq .[0] | JSONGen
type MarketCap struct {
AvailableSupply float64 `json:"available_supply"`
HVolumeUsd float64 `json:"24h_volume_usd"`
Id string `json:"id"`
MarketCapUsd float64 `json:"market_cap_usd"`
Name string `json:"name"`
PercentChange1h float64 `json:"percent_change_1h"`
PercentChange24h float64 `json:"percent_change_24h"`
PercentChange7d float64 `json:"percent_change_7d"`
PriceBtc float64 `json:"price_btc"`
PriceUsd float64 `json:"price_usd"`
Rank int64 `json:"rank"`
Symbol string `json:"symbol"`
TotalSupply float64 `json:"total_supply"`
}
func getAndUnmarshal(url string, target interface{}) error {
...
}
func main() {
link := "https://api.coinmarketcap.com/v1/ticker/ethereum"
resp := make([]MarketCap, 0)
getAndUnmarshal(link, &resp)
log.Printf("Ethereum Id: %s", resp[0].Id)
// 2016/08/22 02:13:23 Ethereum Id: ethereum
}
什么更適合您將取決于您的用例。如果您希望結(jié)構(gòu)反映 API 響應(yīng),那么第一種方法似乎更合適。MarketCap是一件事嗎?我相信,API 只是訪問它的一種方式,比第二種方式更合適。
- 2 回答
- 0 關(guān)注
- 216 瀏覽
添加回答
舉報(bào)