我需要将 JSON 反序列化为具有Vec<Vec<f64>>
字段的结构。JSON 具有数字字符串,因此我需要一个自定义反序列化器f64
在反序列化期间将字符串转换为。
我想反序列化的示例 JSON:
{
"values": [["2", "1.4"], ["8.32", "1.5"]]
}
我的结构是这样的:
#[derive(Deserialize)]
struct Payload {
#[serde(default, deserialize_with = "from_array_of_arrays_of_strs")]
values: Vec<Vec<f64>>,
}
我在 Serde 的示例中看到您可能可以对访问者执行此操作,因此我实现了此访问者:
fn from_array_of_arrays_of_strs<'de, T, D>(deserializer: D) -> Result<Vec<Vec<f64>>, D::Error>
where
T: Deserialize<'de>,
D: Deserializer<'de>,
{
struct F64Visitor(PhantomData<fn() -> Vec<Vec<f64>>>);
impl<'de> Visitor<'de> for F64Visitor {
type Value = Vec<Vec<f64>>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a nonempty sequence of numbers")
}
#[inline]
fn visit_str<E>(self, value: &str) -> Result<f64, E>
where
E: serde::de::Error,
{
self.visit_string(String::from(value))
}
#[inline]
fn visit_string<E>(self, value: String) -> Result<f64, E> {
Ok(value.parse::<f64>().unwrap())
}
#[inline]
fn visit_seq<V, T>(self, mut visitor: V) -> Result<Vec<T>, V::Error>
where
V: SeqAccess<'de>,
{
let mut vec = Vec::new();
while let Some(elem) = try!(visitor.next_element()) {
vec.push(elem);
}
Ok(vec)
}
}
let visitor = F64Visitor(PhantomData);
deserializer.deserialize_seq(visitor)
}
编译器抱怨visit_str
并visit_string
有一个不兼容的特征类型:
error[E0053]: method `visit_str` has an incompatible type for trait
--> src/main.rs:32:9
|
32 | / fn visit_str<E>(self, value: &str) -> Result<f64, E>
33 | | where
34 | | E: serde::de::Error,
35 | | {
36 | | self.visit_string(String::from(value))
37 | | }
| |_________^ expected struct `std::vec::Vec`, found f64
|
= note: expected type `fn(from_array_of_arrays_of_strs::F64Visitor, &str) -> std::result::Result<std::vec::Vec<std::vec::Vec<f64>>, E>`
found type `fn(from_array_of_arrays_of_strs::F64Visitor, &str) -> std::result::Result<f64, E>`
error[E0053]: method `visit_string` has an incompatible type for trait
--> src/main.rs:40:9
|
40 | / fn visit_string<E>(self, value: String) -> Result<f64, E> {
41 | | Ok(value.parse::<f64>().unwrap())
42 | | }
| |_________^ expected struct `std::vec::Vec`, found f64
|
= note: expected type `fn(from_array_of_arrays_of_strs::F64Visitor, std::string::String) -> std::result::Result<std::vec::Vec<std::vec::Vec<f64>>, E>`
found type `fn(from_array_of_arrays_of_strs::F64Visitor, std::string::String) -> std::result::Result<f64, E>`
error[E0049]: method `visit_seq` has 2 type parameters but its trait declaration has 1 type parameter
--> src/main.rs:45:21
|
45 | fn visit_seq<V, T>(self, mut visitor: V) -> Result<Vec<T>, V::Error>
| ^^^^^^ found 2 type parameters, expected 1
我想我对访问者的工作方式没有正确的理解。我可以只有一个访问者来反序列化字符串数组,还是需要一个访问者来反序列化数组,而需要一个访问者来反序列化字符串f64
?
我读了: