在Rust中,我从websocket接收数据。为简单起见,它看起来像这样:
[1, {"a": ["1.2345", 5, "9.8765"]}]
我从websocket获得的字符串确实是双引号“浮点值”(因此是实际字符串)和无引号的整数。
我想将此对象反序列化为一个结构。但是由于返回数组“a”是混合类型,因此我不能使用类似以下内容的东西:
struct MyStruct {
id: i32,
a: [f64; 3],
}
所以我想让我们定义另一个结构:
struct Ask {
price: f64,
whole_lot_volume: i64,
lot_volume: f64
}
struct MyStruct {
id: i32,
a: Ask
}
但是我应该如何为此写反序列化器?查看
serde
文档,我了解我应该为Visitor
编写一个Ask
: impl<'de> Visitor<'de> for Ask {
type Value = ...
}
但是,那么
Value
类型是什么呢?因此,我确定我没有正确理解反序列化过程的工作原理。还是Websocket返回的混合类型数组与Serde反序列化过程不兼容的事实?
最佳答案
Serde可以从类似于序列的结构以及类似于图的结构反序列化为Rust结构。
您的结构几乎正确,但是JSON中有一层额外的层次结构。如果您的JSON是:
{
"id": 1,
"a": [1.2345, 5, 9.8765]
}
然后这将可以正常工作,并带有正确的
serde
批注:use serde::{Serialize, Deserialize};
#[derive(Deserialize)]
struct Ask {
price: f64,
whole_lot_volume: i64,
lot_volume: f64,
}
#[derive(Deserialize)]
struct MyStruct {
id: i32,
a: Ask,
}
如果您无法更改JSON,则可以使用额外的结构层来进行匹配:
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize)]
struct Order {
price: f64,
whole_lot_volume: i64,
lot_volume: f64,
}
#[derive(Debug, Deserialize)]
struct Ask {
a: Order,
}
#[derive(Debug, Deserialize)]
struct MyStruct {
id: i32,
a: Ask,
}
很少需要实现自己的
Visitor
; Deserialize
提供的serde
宏是完全可定制的。但是,如果您想省略多余的结构,那就是您必须要做的。如果某些数字表示为JSON字符串,则可能需要做更多的工作,但是仍然可以在没有自定义
Visitor
实现的情况下进行此操作。看:关于rust - Rust Serde反序列化混合数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65514779/