rust - 在数据的单次迭代中将二进制结构解析为结构
问题描述
我正在编写一个 rust 库,将 LTV(长度类型值)数据反序列化为 rust 结构。二进制 ltv 对象,例如
L T V L T V
02 01 0A 03 02 00 0B
目前正在实施这样的事情:
struct LTVObject{
pub field_1: u8,
pub field_2: u16,
}
impl LTVObject {
pub fn parse(r: &LtvReader) -> LTVResult<Self>{
Ok(LTVObject {
field_1: r.read_field(1)?,
field_2: r.read_field(2)?,
})
}
}
这个实现的问题是每次调用read_field
都是循环遍历 LTV 结构来查找字段。对于大型物体,这非常慢。我想要做的是让 ltv 数据只需要迭代一次。我的想法是将解析更改为:
pub fn parse(r: &LtvReader) -> LTVResult<Self>{
let mut inst = Self{ ... };
for field in r.get_fields(){
match field.id {
1 => inst.field_1 = field.get_value()?,
2 => inst.field_2 = field.get_value()?,
}
}
Ok(inst)
}
但是有一些设计问题我不确定如何解决
- 如果 LTV 中不存在其中一个字段,则返回错误
- 创建没有特征的
inst
变量Default
在实际的库中,parse
函数是从宏生成的,所以我想避免Default
需要在字段类型上实现的约束。
解决方案
将值解析为Option
s,然后检查您是否拥有所有这些值。像这样的东西:
pub fn parse(r: &LtvReader) -> LTVResult<Self> {
let mut field_1 = None;
let mut field_2 = None;
for field in r.get_fields(){
match field.id {
1 => field_1 = Some(field.get_value()?),
2 => field_2 = Some(field.get_value()?),
}
}
Ok(LTVObject {
field_1: field_1.ok_or(Error::MissingField)?,
field_2: field_2.ok_or(Error::MissingField)?,
})
}
推荐阅读
- java - 部分安卓手机无法在设置中打开“关于设备”页面?
- javascript - 如何从 Vue 中的组件更改视图文件上的 :class 名称?
- ubuntu-18.04 - 带有 Ubuntu 18.04 的 MSI GS75 -- 一些 fn 键不起作用(仅音量/亮度起作用)
- kubernetes - Microk8s 上的 Weavescope 无法识别容器
- php - PHP中的JSON字符串到UTF8
- node.js - 通过应用授予对 s3 私有存储桶中用户特定图像的访问权限
- readxl - as.Date() 函数不起作用,我的字符仍然是字符
- python - 在 Python 中使用 MATLAB 回归
- r - 相关矩阵问题
- spring-boot - Elasticsearch 在启动期间抛出错误