generics - 我可以在 Rust 中为一组相关类型提供一个类型参数吗?
问题描述
我正在开发一个适用于 32 位和 64 位架构的 PE 文件的库。一些结构会同时引用虚拟地址(VA,例如ImageBase
)和相对虚拟地址(RVA,例如节偏移),例如:
type VA32 = u32;
type RVA32 = i32;
struct Header32 {
image_base: VA32,
section_offsets: Vec<RVA32>,
}
let hdr = Header32 { /* ... */ };
在处理 32 位 PE 文件时,VA 应该是 32 位且无符号的,而 RVA 应该是 32 位且有符号的。对于 64 位 PE 文件,两种类型都应为 64 位。
我希望我的结构为这些类型使用适当的宽度,可能是通过使它们通用:
struct Header<VA, RVA> {
image_base: VA,
section_offsets: Vec<RVA>,
}
type VA32 = u32;
type RVA32 = i32;
let hdr: Header<VA32, RVA32> = Header { /* ... */ };
但VA32
只有永远存在RVA32
,也VA64
应该永远被提供RVA64
。有没有一种惯用的方式可以表达这一点?
使用完全组成的语法,我希望执行以下操作:
struct Header<Arch> {
image_base: arch.VA,
section_offsets: Vec<arch.RVA>,
}
type Arch32 = { VA: u32, RVA: i32 }
let hdr: Header<Arch32> = Header { /* ... */ };
解决方案
您可以使用具有关联类型和零大小结构的特征作为标记来执行类似于您的组合语法的操作。
trait Arch {
type VA;
type RVA;
}
#[derive(Debug)]
struct Arch32;
impl Arch for Arch32 {
type VA = u32;
type RVA = i32;
}
#[derive(Debug)]
struct Arch64;
impl Arch for Arch64 {
type VA = u64;
type RVA = i64;
}
#[derive(Debug)]
struct Header<T: Arch> {
image_base: T::VA,
section_offsets: Vec<T::RVA>,
}
推荐阅读
- firebase - 如何在firebase中自动导入谷歌云存储桶?
- flutter - Flutter 从子级更新父级 UI
- javascript - 抓取网站/域并检查是否存在某种格式的 URL - JavaScript
- tensorflow - 使用 tf.data.Dataset 在张量流中进行多热编码
- php - 在 Laravel 中播种用户配置文件数据的问题
- sql-server - SQL Server:在 SELECT 中的 MAX 语句给出的结果上加入
- documentation - ERR_FILE_NOT_FOUND 创建 Docusaurus 文件时
- python - Pandas - 不同值的滚动累积计数
- javascript - 动态过滤嵌套 javascript 对象数组中的数据
- c# - 如何修复 gRPC 和 C# 的“命名空间名称“故障”的类型在命名空间中不存在”?