2 回答

TA贡献1893条经验 获得超10个赞
您需要一个自定义的Unmarshaler. 这里是。
请注意,BitfinexOrderBook定义与您的定义略有不同。里面有一个错误。
// BitfinexOrderBook is a book of orders.
type BitfinexOrderBook struct {
Asks []BitfinexOrder `json:"asks"`
Bids []BitfinexOrder `json:"bids"`
}
// BitfinexOrder is a bitfinex order.
type BitfinexOrder struct {
Price string
Volume string
Timestamp time.Time
}
// UnmarshalJSON decode a BifinexOrder.
func (b *BitfinexOrder) UnmarshalJSON(data []byte) error {
var packedData []json.Number
err := json.Unmarshal(data, &packedData)
if err != nil {
return err
}
b.Price = packedData[0].String()
b.Volume = packedData[1].String()
t, err := packedData[2].Int64()
if err != nil {
return err
}
b.Timestamp = time.Unix(t, 0)
return nil
}
另请注意,此自定义解组器功能允许您将价格或交易量转换为浮点数,这可能是您想要的。

TA贡献1876条经验 获得超6个赞
虽然您可以通过使用反射来破解自己的方式,或者甚至可以编写自己的解析器,但最有效的方法是实现一个json.Unmarshaler
.
不过,还有一些问题。
您正在将 a 转换
json array
为struct
,而不仅仅是其中的interface{}
元素,所以它应该是:Asks []BitfinexOrder
和Bids []BitfinexOrder
.您需要包装结构
BitfinexOrderBook
以使其与数据一起工作。它比使用反射简单得多。默认情况下,将 a
json.Unmarshal
解组json number
为 float64,这在解析时不是一件好事timestamp
。您可以使用json.NewDecoder
来获取解码器,然后使用Decoder.UseNumber
来强制使用字符串。
例如,
func (bo *BitfinexOrder) UnmarshalJSON(data []byte) error {
dec := json.NewDecoder(bytes.NewReader(data))
dec.UseNumber()
var x []interface{}
err := dec.Decode(&x)
if err != nil {
return errParse(err.Error())
}
if len(x) != 3 {
return errParse("length is not 3")
}
price, ok := x[0].(string)
if !ok {
return errParse("price is not string")
}
volume, ok := x[1].(string)
if !ok {
return errParse("volume is not string")
}
number, ok := x[2].(json.Number)
if !ok {
return errParse("timestamp is not number")
}
tint64, err := strconv.ParseInt(string(number), 10, 64)
if err != nil {
return errParse(fmt.Sprintf("parsing timestamp: %s", err))
}
*bo = BitfinexOrder{
Price: price,
Volume: volume,
Timestamp: time.Unix(tint64, 0),
}
return nil
}
和 main func(包装结构):
func main() {
x := struct {
Result struct{ LINKUSD BitfinexOrderBook }
}{}
err := json.Unmarshal(data, &x)
if err != nil {
log.Fatalln(err)
}
bob := x.Result.LINKUSD
fmt.Println(bob)
}
游乐场链接: https: //play.golang.org/p/pC124F-3M_S。
注意:操场链接使用辅助函数来创建错误。有些人可能会争辩说最好命名帮助函数NewErrInvalidBitfinexOrder或重命名错误。这不是这个问题的范围,我认为为了打字,我暂时保留简称。
- 2 回答
- 0 关注
- 133 浏览
添加回答
举报