【问题标题】:Unmarshaling json into a type将 json 解组为类型
【发布时间】:2018-05-11 17:22:46
【问题描述】:

我得到以下数据:

{
  "timestamp": "1526058949",
  "bids": [
    [
      "7215.90",
      "2.31930000"
    ],
    [
      "7215.77",
      "1.00000000"
    ]
  ]
}

通过 websocket,我想将其解组为

type OrderBookItem struct {
    Price  string
    Amount string
}

type OrderBookResult struct {
    Timestamp string            `json:"timestamp"`
    Bids      []OrderBookItem `json:"bids"`
    Asks      []OrderBookItem `json:"asks"`
}

解组它:

s := e.Data.(string)
d := &OrderBookResult{}
err := json.Unmarshal([]byte(s), d)
if err == nil {
 ....
} else {
 fmt.Println(err.Error())
}

但我不断收到错误消息:

json: 无法将字符串解组到 Go 结构字段中 Feed.OrderBookItem 类型的 OrderBookResult.bids

当我将结构更改为

type OrderBookResult struct {
        Timestamp string     `json:"timestamp"`
        Bids      [][]string `json:"bids"`
        Asks      [][]string `json:"asks"`
} 

它有效。我希望它们被定义为float64,它们就是这样。我需要改变什么?

【问题讨论】:

  • 你找到了一个有效的结构,你的问题是什么?
  • 如果你看到错误是由于 OrderBookItem 是一个结构而不是一个项目数组,这就是错误的原因

标签: go struct


【解决方案1】:

正如错误所说:

json: 无法将字符串解组到 Go 结构字段中 Feed.OrderBookItem 类型的 OrderBookResult.bids

我们无法将 OrderBookResult.bids 字符串切片转换为 OrderBookItem 结构体

实现UnmarshalJSON接口,将数组转换为priceamount的对象OrderBookItem结构。如下所示

package main

import (
    "fmt"
    "encoding/json"
)

type OrderBookItem struct {
    Price  string
    Amount string
}

func(item *OrderBookItem) UnmarshalJSON(data []byte)error{
    var v []string
    if err:= json.Unmarshal(data, &v);err!=nil{
        fmt.Println(err)
        return err
    }
    item.Price  = v[0]
    item.Amount = v[1]
    return nil
}

type OrderBookResult struct {
    Timestamp string            `json:"timestamp"`
    Bids      []OrderBookItem   `json:"bids"`
    Asks      []OrderBookItem   `json:"asks"`
}

func main() {
    var result OrderBookResult
    jsonString := []byte(`{"timestamp": "1526058949", "bids": [["7215.90", "2.31930000"], ["7215.77", "1.00000000"]]}`)
    if err := json.Unmarshal([]byte(jsonString), &result); err != nil{
        fmt.Println(err)
    }
    fmt.Printf("%+v", result)
}

Playground working example

有关更多信息,请阅读 Unmarshaler 的 GoLang 规范

【讨论】:

  • 您不需要所有不必要的接口转换,只需将 [2] 字符串数组传递给 json.Unmarshall play.golang.org/p/kRYXtDZiIB7
  • @mpm 是的,我们可以做到这一点,这就是为什么我在回答中提到它是 json 中的一段字符串。所以我已经转换成相同的对象类型。如果 OP 想要在不更改结构的情况下插入相同的结构。但是感谢您的通知。
  • 我认为 mpm 是说您仍然可以将数据放入结构中,但不需要在途中进行类型转换
【解决方案2】:

您将出价视为两个单独字符串的结构,而它们实际上是 JSON 中的一段字符串。如果您将 OrderBookItem 更改为

type OrderBookItem []string

这就是您在第二位中定义它们的方式,这是有效的。

要访问您只需要执行的值: 价格 := d.Bids[0] 金额:= d.Bids[1]

【讨论】:

  • 谢谢你的作品。是否可以将类型定义为浮点数?如果我fmt.Println(reflect.TypeOf(o.Asks[1][0]))我得到string
  • @Tino,是的,使用字符串选项:Bids []float64 json:"bids,string"。有关其他选项,请参阅 json.Marshal
猜你喜欢
  • 1970-01-01
  • 2016-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-06
  • 2020-10-14
  • 1970-01-01
相关资源
最近更新 更多