4 个版本
0.0.4 | 2022年10月5日 |
---|---|
0.0.3 | 2022年7月15日 |
0.0.2 | 2022年7月4日 |
0.0.1 | 2022年6月15日 |
#1100 在 Rust 模式
77KB
1.5K SLoC
Projecture
目前处于概念验证阶段,并且内部使用大量尚未经过实战考验的不安全代码,因此请在使用时自行承担风险。如果您熟悉不安全 Rust,我将非常感激您进行稳定性审查。
允许执行几乎任意的类型投影。与其他执行类似功能的 crate 相比,它更加通用,无需程序宏,并且不对目标结构施加额外的要求,如果目标结构位于外部 crate 中,则该 crate 不必明确添加对这种投影的支持(pin 投影是例外)。
尽管目前这个 crate 还不支持枚举,但将来会添加。
目前可以执行以下类型的投影:
- 解构投影(类似于常规
let <pattern>
,但也支持解引用模式,并且当结构体实现了Drop
(只是没有被调用)时也能工作。
注意:由于声明宏的限制,目前未提及的字段将被泄露。 - 引用投影(类似于
let <pattern>
中的 match 语法,但也支持解引用模式) Pin
投影Cell
投影MaybeUninit
投影Atomic
(来自atomic
crate)投影Option
投影(与其他类型的投影一起工作)RefCell
保护投影- 原始指针投影(
*const T
,*mut T
,NonNull<T>
)
还增加了两种可投影指针类型
generic::GenericPointer
- 允许编写泛型引用类型的代码。OwningRef
- 语义上拥有数据的引用(有时在各种提案中称为&own T
)。在nightly版本(带有nightly
功能)中,它允许你创建接受Self
值的对象安全特例。
在可能的情况下,投影还可以通过一个 Deref
来进行(包括通过 DerefOwned
来按值解引用)。
以下是你可以做什么的概述,有关更多用法详情,请查看 project
! 宏。
# use std::cell::Cell;
# use std::marker::PhantomPinned;
# use std::pin::Pin;
# use std::rc::Rc;
# use atomic::Atomic;
# use projecture::project;
# use projecture::pin_projectable;
struct Foo {
a: Bar,
b: Rc<Cell<Bar>>,
c: Pin<Box<Bar>>,
d: Atomic<Bar>,
}
struct Bar(usize,PhantomPinned);
// needed only for pin projections
pin_projectable!(Bar);
fn test(arg: &Foo) {
project!(
let Foo {
a: Bar (e, ..),
b: *Bar{ 0: cell },
c: *Bar (_, f) ,
d: Bar(atomic, ..),
} = arg);
let _: &usize = e;
let _: &Cell<usize> = cell;
let _: Pin<& PhantomPinned> = f;
let _: &Atomic<usize> = atomic;
let _: &usize = project!(arg -> a -> 0);
let _: &Cell<usize> = project!(arg -> b -> 0);
let _: Pin<& PhantomPinned> = project!(arg -> c -> 1);
let _: &Atomic<usize> = project!(arg -> d -> 0);
}
此外,还允许依赖的crate通过特例定义自己的投影。例如,查看 atomic
模块中透明字段包装器的投影或 Pin
在自定义引用类型上的投影。
MSRV: 1.54
许可协议:MIT