获取带接口的struct的值

时间:2018-02-23 16:18:22

标签: go struct request

我试图解析此请愿书(https://www.binance.com/api/v1/depth?symbol=MDABTC&limit=500

我为它创建一个结构有很多问题,所以我使用了一个自动化工具,这就是我的结构:

type orderBook struct {
    Bids         [][]interface{} `json:"Bids"`
    Asks         [][]interface{} `json:"Asks"`
}

我通过以下方式恢复并解析请愿书:

url := "https://www.binance.com/api/v1/depth?symbol=MDABTC&limit=500"
resp, err := http.Get(url)
if err != nil {
    panic(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
    panic(err)
}else{
    book := orderBook{}
if err := json.Unmarshal(body, &book); err != nil {
    panic(err)
}

但每当我尝试使用struct进行操作时,例如:

 v := book.Asks[i][0] * book.Asks[i][1]

我收到错误:

  

无效操作:book.ask [i] [0] * book.assks [i] [1](operator * not   在接口上定义)

我该如何定义它?我是否需要为bids/asks创建一个结构,如果是这样,它会是什么样的?

对不起,如果这看起来很基本,我就开始学习了。

2 个答案:

答案 0 :(得分:1)

在Golang Spec

  

对于接口类型的表达式x和类型T,表示主要的   表达

x.(T)
  

断言x不是nil,并且存储在x中的值是T类型。   符号x。(T)称为类型断言。

获取字符串类型的基础值,您需要从接口键入assert to string。

books.Asks[0][0].(string)

要对其执行算术运算,您需要将字符串转换为float64以考虑小数值

v := strconv.ParseFloat(books.Asks[0][0].(string), 64) * strconv.ParseFloat(books.Asks[0][1].(string), 64)

Go playground

上的结帐代码

答案 1 :(得分:1)

请注意,您可以通过实现json.Unmarshaler interface来定义从JSON文档中解组的正确结构。

例如(on the Go Playground):

type OrderBook struct {
  Asks, Bids   []Order
  LastUpdateId int
}

type Order struct {
  Price, Volume float64
}

func (o *Order) UnmarshalJSON(bs []byte) error {
  values := make([]interface{}, 0, 3)
  err := json.Unmarshal(bs, &values)
  if err != nil {
    return err
  }
  // TODO: more error checking re: len(values), and their types.
  price, err := strconv.ParseFloat(values[0].(string), 10)
  if err != nil {
    return err
  }
  volume, err := strconv.ParseFloat(values[1].(string), 10)
  if err != nil {
    return err
  }
  *o = Order{price, volume}
  return nil
}

因此,解开那些文件似乎是惯用的:

func main() {
  book := OrderBook{}
  err := json.Unmarshal([]byte(jsonstr), &book)
  if err != nil {
    panic(err)
  }
  fmt.Printf("Asks:   %#v\n", book.Asks)
  fmt.Printf("Bids:   %#v\n", book.Bids)
  fmt.Printf("Update: %#v\n", book.LastUpdateId)
  // Asks:   []main.Order{main.Order{Price:0.00013186, Volume:167}, main.Order{Price:0.00013187, Volume:128}, ...
  // Bids:   []main.Order{main.Order{Price:0.00013181, Volume:110}, main.Order{Price:0.00013127, Volume:502}, ...
  // Update: 14069188
}