使用Golang映射对结构的响应

问题描述 投票:1回答:2

我试图使用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
2个回答
5
投票

映射不起作用。相反,您应该使用地图:

    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对象中的键应该对应于结构中的某个值。 Golang JSON映射根本不起作用。

但是,您可以使用“Price”类型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}
  // }
}
© www.soinside.com 2019 - 2024. All rights reserved.