1

次の API 応答を逆シリアル化しようとしています (簡単にするために、配列の 2 つのスライスのみをコピーしますが、実際にはもっと大きくなります)。このコードは、例を示すために単純化しすぎています。

API 応答:

[[1609632000000,32185,32968,34873,31975,18908.90248876],[1609545600000,29349.83250154,32183,33292,29000,22012.92431526]]

したがって、これは大きな配列/ベクトルであり、6 つの整数 OR 浮動小数点数を持つ配列/ベクトルで構成されます (位置も異なります)。

このために、ジェネリックを使用しようとしていますが、コンパイルできないため、何かが足りないようです..

それは失敗しています

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("invalid type: integer `1609632000000`, expected struct T", line: 1, column: 15) }'

use blocking::Response;
use serde::{Deserialize, Serialize};
use reqwest::{blocking, Error, StatusCode};

struct allData<T> {
    data: Slice<T>
}

#[derive(Debug, Serialize, Deserialize)]
struct Slice<T>{
    data1: T,
    data2: T,
    data3: T,
    data4: T,
    data5: T,
    data6: T,

}


fn get_data() -> Option<Slice> /*I know the signature is not correct, read until the end for the correct one*/ {
    let url = format!("{}", my_url_string);
    let response: Slice<T> = blocking::get(&url).unwrap().json().unwrap();
    Some(response);


}

fn main() {
   let call_the_api = get_data();
   println!("{:?}", call_the_api);
}

「スライス」のベクトルを返すことができるジェネリックで構造体を使用する正しい方法は何でしょうか。

すなわち。

Vector{
    Slice {
     data1,
     data2,
     data3,
     data4,
     data5,
     data6,
},
    Slice {
      data1, 
      data2,
      data3,
      data4,
      data5,
      data6,
}
}
4

1 に答える 1

2

構造体の派生はDeserializeSliceJSON 配列では機能しません。代わりに、 fieldsdata1などを含む JSON dict がdata2必要です。おそらく、Deserialize型の特性を手動で実装したくないのでVec<Vec<T>>、ネストされた配列をモデル化する必要があります。

#[derive(Deserialize)]
#[serde(transparent)]
struct AllData<T>(Vec<Vec<T>>);

Vecこのタイプは、 内のすべての項目を のタイプに制限しますTf64これは、 someと someを使用できないことを意味しi64ます。すべて float またはすべて int になります。このラッパーを float と int の両方でジェネリックにするには、おそらくいくつかの列挙型が必要になるでしょう:

#[derive(Deserialize)]
// note, this causes deserialization to try the variants top-to-bottom
#[serde(untagged)]
enum FloatOrInt {
    Int(i64),
    Float(f64),
}

列挙型では、型パラメーターTonAllDataはもう必要ありません。次のようにできます。

#[derive(Deserialize)]
#[serde(transparent)]
struct AllData(Vec<Vec<FloatOrInt>>);

内側の配列の長さが常に 6 であることが確実な場合は、配列に置き換えることができます[FloatOrInt; 6]

まとめると、次のようになります。

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=52bd3ce7779cc9b7b152c681de8681c4

于 2021-03-15T16:22:53.367 に答える