Get value of struct with interfaces

前端 未结 2 1929
夕颜
夕颜 2021-01-29 10:39

I\'m trying to parse this petition (https://www.binance.com/api/v1/depth?symbol=MDABTC&limit=500)

I was having tons of problems to create an struct for it, so I used

相关标签:
2条回答
  • 2021-01-29 11:13

    Note that you could define proper structs that unmarshal from the JSON document by implementing the json.Unmarshaler interface.

    For example (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
    }
    

    As such, unmarshaling those documents looks idiomatic:

    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
    }
    
    0 讨论(0)
  • 2021-01-29 11:19

    In Golang Spec

    For an expression x of interface type and a type T, the primary expression

    x.(T)
    

    asserts that x is not nil and that the value stored in x is of type T. The notation x.(T) is called a type assertion.

    Fetching an underlying value of string type you need to type assert to string from interface.

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

    For performing an arithmetic operation on same you needs to convert string into float64 to take into account decimal values

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

    Checkout code on Go playground

    0 讨论(0)
提交回复
热议问题