You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言如何解析HTTP响应数组,获取第二个子数组的第二个元素?

Go解析Binance K线数据获取指定元素

方法一:直接解析为二维任意类型数组

Binance返回的K线是混合类型的二维数组(包含整数、字符串),可以直接用[][]interface{}解析,通过索引获取目标元素:

package main

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

func main() {
    // 发起GET请求
    response, err := http.Get("https://api.binance.com/api/v3/klines?symbol=ETHUSDT&interval=5m&limit=5")
    if err != nil {
        fmt.Println("请求失败:", err)
        return
    }
    // 确保响应体最终关闭
    defer response.Body.Close()

    // 检查响应状态码是否正常
    if response.StatusCode != http.StatusOK {
        fmt.Println("响应异常,状态码:", response.StatusCode)
        return
    }

    // 读取响应体内容
    body, err := ioutil.ReadAll(response.Body)
    if err != nil {
        fmt.Println("读取响应体失败:", err)
        return
    }

    // 解析为二维任意类型数组
    var klines [][]interface{}
    err = json.Unmarshal(body, &klines)
    if err != nil {
        fmt.Println("JSON解析失败:", err)
        return
    }

    // 校验数组长度是否满足需求
    if len(klines) < 2 {
        fmt.Println("返回的K线数据不足2条")
        return
    }
    secondKline := klines[1] // 第二个子数组(索引从0开始)
    if len(secondKline) < 2 {
        fmt.Println("K线子数组元素数量不足")
        return
    }

    // 获取第二个子数组的第二个元素
    targetElement := secondKline[1]
    fmt.Println("目标元素值:", targetElement)
}

方法二:定义结构体实现类型安全解析

如果需要更清晰的类型管理,可以把K线的固定字段映射为结构体(Binance K线子数组顺序:时间戳、开盘价、最高价、最低价、收盘价、成交量、结束时间、成交额、成交笔数、主动买入成交量、主动买入成交额、忽略字段):

package main

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

// Kline 对应Binance返回的单条K线数据结构
type Kline struct {
    OpenTime           int64  // 数组第0位:开盘时间戳
    OpenPrice          string // 数组第1位:开盘价(用字符串避免浮点数精度丢失)
    HighPrice          string
    LowPrice           string
    ClosePrice         string
    Volume             string
    CloseTime          int64
    QuoteAssetVolume   string
    NumberOfTrades     int
    TakerBuyVolume     string
    TakerBuyQuoteVolume string
    Ignore             string
}

// UnmarshalJSON 自定义解析逻辑,将数组转为结构体
func (k *Kline) UnmarshalJSON(data []byte) error {
    var arr []interface{}
    if err := json.Unmarshal(data, &arr); err != nil {
        return err
    }
    if len(arr) < 12 {
        return fmt.Errorf("无效的K线数据长度")
    }
    k.OpenTime = int64(arr[0].(float64))
    k.OpenPrice = arr[1].(string)
    k.HighPrice = arr[2].(string)
    k.LowPrice = arr[3].(string)
    k.ClosePrice = arr[4].(string)
    k.Volume = arr[5].(string)
    k.CloseTime = int64(arr[6].(float64))
    k.QuoteAssetVolume = arr[7].(string)
    k.NumberOfTrades = int(arr[8].(float64))
    k.TakerBuyVolume = arr[9].(string)
    k.TakerBuyQuoteVolume = arr[10].(string)
    k.Ignore = arr[11].(string)
    return nil
}

func main() {
    response, err := http.Get("https://api.binance.com/api/v3/klines?symbol=ETHUSDT&interval=5m&limit=5")
    if err != nil {
        fmt.Println("请求失败:", err)
        return
    }
    defer response.Body.Close()

    if response.StatusCode != http.StatusOK {
        fmt.Println("响应异常,状态码:", response.StatusCode)
        return
    }

    body, err := ioutil.ReadAll(response.Body)
    if err != nil {
        fmt.Println("读取响应体失败:", err)
        return
    }

    // 解析为Kline结构体数组
    var klines []Kline
    err = json.Unmarshal(body, &klines)
    if err != nil {
        fmt.Println("JSON解析失败:", err)
        return
    }

    if len(klines) < 2 {
        fmt.Println("返回的K线数据不足2条")
        return
    }

    // 获取第二个K线的开盘价(对应子数组第二个元素)
    targetPrice := klines[1].OpenPrice
    fmt.Println("第二个K线的开盘价:", targetPrice)
}

关键提示

  • Go数组索引从0开始,第二个子数组对应索引1,子数组的第二个元素对应索引1
  • 价格字段推荐用字符串存储,避免浮点数精度丢失
  • 必须添加响应状态码检查、错误处理,避免程序意外崩溃

内容的提问来源于stack exchange,提问作者user2497209

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 18:24:57