1 个不稳定版本
0.1.0 | 2024年5月15日 |
---|
#2023 在 Rust 模式
16KB
167 行
Perforate
Perforate 通过生成结构体的变体,允许结构体字段“分割”为与结构体其他部分分离,就像在 分割借用 中的情况。
这类似于使用 mem::take 或其他替换函数的效果,但可以在不实现 Default 或无法构建合适占位符的字段上执行。
用法
在栈上的所有者结构体上穿孔。
use perforate::Perforate;
#[derive(Perforate)]
#[repr(C)]
pub struct TestStruct {
#[perforate]
one: String,
two: u64,
}
let test_struct = TestStruct{one: "one".to_string(), two: 42};
let (perforated, one) = test_struct.perforate_one();
assert_eq!(core::mem::size_of::<TestStruct>(), core::mem::size_of_val(&perforated));
assert_eq!(perforated.two, 42);
assert_eq!(one, "one");
let original = perforated.replace_perf(one);
assert_eq!(original.two, 42);
assert_eq!(original.one, "one");
或在所有者盒子中的结构体上穿孔。
use perforate::Perforate;
#[derive(Perforate)]
#[repr(C)]
pub struct TestStruct {
#[perforate]
one: String,
two: u64,
}
let test_struct = Box::new(TestStruct{one: "one".to_string(), two: 42});
let (perforated_box, one) = TestStruct::boxed_perforate_one(test_struct);
assert_eq!(perforated_box.two, 42);
assert_eq!(one, "one");
let original_box = TestStruct::boxed_replace_one(perforated_box, one);
assert_eq!(original_box.two, 42);
assert_eq!(original_box.one, "one");
注意事项
如果结构体具有仅由带有 #[perforate]
属性的字段使用的泛型参数或生命周期,您必须向您的结构体添加 PhantomData 以防止编译错误。此外,在 问题 合并之前,您不能在 稳定
上对具有泛型类型参数的字段进行穿孔。
您可以访问穿孔结构体的其他“未穿孔”字段,但是穿孔后的结构体是一个新类型,不包含其祖先的任何特性行为。这包括自定义的 Drop 特性。因此,如果您的结构体需要特殊的清理行为,您必须在丢弃之前重新组装它。
依赖关系
~290–740KB
~17K SLoC