鸿蒙传说
“对可能发生的事情有什么想法吗?”"XXBTZUSD"JSON数组中的元素本身就是数组,即"XXBTZUSD"是数组的数组。该OHLC类型是结构类型。stdlib 本身不会将 JSON 数组解组为 Go 结构。Go 结构可用于解组 JSON 对象。JSON 数组可以解组为 Go 切片或数组。如果您只是打印来自 json.Unmarshal 的错误,您会清楚地看到这就是问题所在:json:无法将数组解组到main.OHLC 类型的 Go 结构字段 Trades.result.XXBTZUSDhttps://go.dev/play/p/D4tjXZVzDI_w如果要将 JSON 数组解组为 Go 结构,则必须让 Go 结构类型实现json.Unmarshaler接口。func (o *OHLC) UnmarshalJSON(data []byte) error { // first unmarshal the array into a slice of raw json raw := []json.RawMessage{} if err := json.Unmarshal(data, &raw); err != nil { return err } // create a function that unmarshals each raw json element into a field unmarshalFields := func(raw []json.RawMessage, fields ...interface{}) error { if len(raw) != len(fields) { return errors.New("bad number of elements in json array") } for i := range raw { if err := json.Unmarshal([]byte(raw[i]), fields[i]); err != nil { return err } } return nil } // call the function return unmarshalFields( raw, &o.Time, &o.Open, &o.High, &o.Low, &o.Close, &o.Vwa, &o.Volume, &o.Count, )}https://go.dev/play/p/fkFKLkaNaSU
ITMISS
您的代码有一些问题:从行尾删除分号,这是多余的。fmt.Errorf返回错误,而不是打印它,每次检查你的错误并传播它。我们可以在 golang 中将数字数组和字符串转换为结构。为了实现您想要的输出,我们需要先转换为中间容器,然后再转换为我们想要的输出:package mainimport ( "errors" "fmt" "log" "net/http" //"strings" "encoding/json" "io/ioutil")type Resp struct { Error []string `json:"error"` Result Trades `json:"result"`}type IntermediateResp struct { Error []string `json:"error"` Result IntermediateTrades `json:"result"`}type IntermediateTrades struct { Pair [][]interface{} `json:"XXBTZUSD"` Last int `json:"last"`}type Trades struct { Pair []OHLC `json:"result"` Last int `json:"last"`}type OHLC struct { TT float64 Open string High string Low string Close string Vwap string Volume string Count float64}/*func main() { var data = [...]Trade{ Trade{5, "op", "hi", "lo", "cl", "vw", "vo", 2}, Trade{5, "op", "hi", "lo", "cl", "vw", "vo", 2}, }}*/func main() { fmt.Println("in main") err := getOhlc() if err != nil { log.Fatal(err) }}func buildOHLC(l []interface{}) (*OHLC, error) { if len(l) < 8 { return nil, errors.New("short list") } return &OHLC{ TT: l[0].(float64), Open: l[1].(string), High: l[2].(string), Low: l[3].(string), Close: l[4].(string), Vwap: l[5].(string), Volume: l[6].(string), Count: l[7].(float64), }, nil}func convert(r IntermediateResp) (*Resp, error) { result := &Resp{Error: r.Error, Result: Trades{Pair: make([]OHLC, len(r.Result.Pair)), Last: r.Result.Last}} for i, v := range r.Result.Pair { ohlc, err := buildOHLC(v) if err != nil { return nil, err } result.Result.Pair[i] = *ohlc } return result, nil}func getOhlc() error { fmt.Println("in ohlc func") resp, err := http.Get("https://api.kraken.com/0/public/OHLC?pair=XXBTZUSD") if err != nil { return fmt.Errorf("error after request, %v", err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) fmt.Println(string(body)) if err != nil { return fmt.Errorf("error when reading %v", err) } var jsonData IntermediateResp err = json.Unmarshal(body, &jsonData) if err != nil { return fmt.Errorf("error when unmarshalling %v", err) } if len(jsonData.Error) > 0 { return fmt.Errorf("error") } convertedOhlc, err := convert(jsonData) if err != nil { return fmt.Errorf("error when convertedOhlc %v", err) } fmt.Println(convertedOhlc) return nil}我们定义 IntermediateResp 和 IntermediateTrades 用于 Unmarshaling json,然后将其转换为实际的 Resp。Trades我认为另一种方法是对结构使用自定义 Unmarshal 。