【问题标题】:Map response to a struct using Golang使用 Golang 将响应映射到结构
【发布时间】:2018-06-13 08:56:51
【问题描述】:

我正在尝试使用 Golang 将来自 API 的响应映射到结构。

当我在浏览器中查看链接时返回的 JSON 如下:

{
"GBP": 657.54
}

我只想将它映射到一个简单的结构,如下所示:

type Price struct {
    Name  string
    Value float64
}

这是我当前的代码。

func FetchCoinPrice(fsym string, tsyms string) Price {
    url := fmt.Sprintf("https://min-api.cryptocompare.com/data/price?fsym=" + fsym + "&tsyms=" + tsyms)

    fmt.Println("Requesting data from " + url)

    price := Price{}

    // getting the data using http
    request, err := http.Get(url)
    if err != nil {
        log.Fatal(err.Error())
    }

    // Read the response body using ioutil
    body, err := ioutil.ReadAll(request.Body)
    if err != nil {
        log.Fatal(err.Error())
    }

    defer request.Body.Close()

    if request.StatusCode == http.StatusOK {
        json.Unmarshal(body, &price)
    }

    return price

}

目前我收到的只是一个空结构,我知道该链接正在返回正确的数据,并且我已经在浏览器中对其进行了测试。

【问题讨论】:

标签: go


【解决方案1】:

映射不是那样工作的。相反,您应该使用地图:

    data := []byte(`{
       "GBP": 657.54
     }`)

    priceMap := map[string]float64{}
    err := json.Unmarshal(data, &priceMap)
    // Check your errors!
    if err != nil {
      log.Fatal(err.Error())
    }
    fmt.Println(priceMap)

这将打印:

map[GBP:657.54]

然后您可以遍历地图并构建您上面提到的结构,或者如果您知道货币,则直接访问条目。例如:priceMap["GBP"]

你真的应该检查你的错误,特别是如果你没有从Unmarshal得到你期望的输出。

【讨论】:

    【解决方案2】:

    问题在于解组器无法猜测 JSON 对象中的 keys 应该对应于结构中的某些 value。 Golang JSON 映射根本不能那样工作。

    但是,您可以使您的“价格”类型 implement json.Unmarshaler 将消息反序列化为浮点映射 (map[string]float64),然后确保形状正确并相应地填充结构:

    func (p *Price) UnmarshalJSON(bs []byte) error {
      kvs := map[string]float64{}
      err := json.Unmarshal(bs, &kvs)
      if err != nil {
        return err
      }
      if len(kvs) != 1 {
        return fmt.Errorf("expected 1 key, got %d", len(kvs))
      }
      for name, value := range kvs {
        p.Name, p.Value = name, value
      }
      return nil
    }
    
    func main() {
      jsonstr := `[{"GBP":657.54},{"USD":123.45}]`
      ps := []Price{}
      err := json.Unmarshal([]byte(jsonstr), &ps)
      if err != nil {
        panic(err)
      }
      // ps=[]main.Price{
      //   main.Price{Name:"GBP", Value:657.54},
      //   main.Price{Name:"USD", Value:123.45}
      // }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-24
      • 2018-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多