2 个不稳定版本
0.2.0 | 2020 年 6 月 5 日 |
---|---|
0.1.0 | 2020 年 2 月 2 日 |
#1067 in 并发
每月 25 次下载
38KB
657 行
refptr
Rust 中侵入式引用计数结构体的宏、属性和特性。请参阅文档以获取更多信息。
lib.rs
:
Rust 中侵入式引用计数结构体的宏、属性和特性。
该crate围绕操作侵入式引用计数结构体而构建。这些结构体使用 #[refcounted]
属性声明,使用 make_refptr
宏构造,并使用 RefPtr
和 WeakPtr
智能指针类型管理其生命周期。
声明引用计数结构体
可以将 #[refcounted]
属性应用于 struct
声明,以将其标记为引用计数。引用计数结构体始终在堆上分配,并使用 make_refptr
辅助宏构造。
示例
#[refcounted(local)]
struct HeapInteger {
value: Cell<i32>,
}
let orig = make_refptr!(HeapInteger { value: Cell::new(10) });
let copy = orig.clone();
orig.value.set(20);
assert_eq!(copy.value.get(), 20);
分配
使用 #[refcounted]
声明的结构体使用 make_refptr!
宏在堆上构造。此宏接受结构体字面量语法,但将值构造在堆上。
这是为了确保类型始终在堆上以进行侵入式引用计数。
示例
let ptr = make_refptr!(HeapPair { t: 10, u: 20 });
assert_eq!(ptr.t, 10);
assert_eq!(ptr.u, 20);
终止和 Drop
使用 #[refcounted]
注释的类型不能手动实现 Drop
,因为这会在对象正在释放时允许恢复 RefPtr<Self>
,从而导致使用后释放。
如果需要最终化方法,则#[refcounted(finalize)]
属性提供了对自定义最终化的支持。如果启用了最终化,则在丢弃任何字段之前会调用一个fn finalize(&self)
方法。
在finalize
方法执行期间,代码可能获得一个新的强引用,这可能导致在返回后结构体不会被丢弃。因此,finalize
可能在结构体的整个生命周期中被多次调用。
配置
#[refcounted(atomic)]
和#[refcounted(local)]
在类似Arc
的原子引用计数或类似Rc
的线程本地引用计数之间进行选择。只要所有字段都可以共享,原子引用计数的类型可以在线程之间共享。
必须指定引用计数的原子性。
示例
#[refcounted(atomic)]
struct HeapInt { i: i32 }
let here = make_refptr!(HeapInt { i: 10 });
let thread = thread::spawn(move || here.i);
assert_eq!(thread.join().unwrap(), 10);
#[refcounted(weak)]
添加了对弱引用计数和WeakPtr
智能指针类型的支持。此注释可以与其他注释结合使用。
示例
#[refcounted(atomic, weak)]
struct HeapInt { i: i32 }
let here = make_refptr!(HeapInt { i: 10 });
let weak = WeakPtr::new(&*here);
assert_eq!(weak.upgrade().unwrap().i, 10);
drop(here);
assert!(weak.upgrade().is_none());
#[refcounted(finalize)]
在尝试销毁结构体之前,会在结构体上调用一个fn finalize(&self)
方法。有关详细信息,请参阅“最终化”部分。此注释可以与其他注释结合使用。
支持使用RefPtr
引用的结构体会被标记为具有#[refcounted(...)]
属性。此属性会生成所需的非安全代码、额外成员和特质实现。
#[refcounted(atomic, finalize)]
struct FinalizeExample {}
static FINALIZED: AtomicBool = AtomicBool::new(false);
impl FinalizeExample {
fn finalize(&self) {
FINALIZED.store(true, SeqCst);
}
}
let orig = make_refptr!(FinalizeExample {});
assert_eq!(FINALIZED.load(SeqCst), false);
let copy = orig.clone();
assert_eq!(FINALIZED.load(SeqCst), false);
drop(orig);
assert_eq!(FINALIZED.load(SeqCst), false);
drop(copy);
assert_eq!(FINALIZED.load(SeqCst), true);
特质对象
#[refcounted]
也可以用于管理特质对象的生命周期,通过在特质对象的层次结构中包含Refcounted
特质。需要指定关联类型Rc
以保持对象安全。
refcnt
模块包含此crate使用的特定引用计数类型。
示例
trait MyTrait : Refcounted<Rc = refcnt::AtomicWeak> {
fn my_trait_method(&self) -> i32;
}
#[refcounted(atomic, weak)]
struct MyStruct { i: i32 }
impl MyTrait for MyStruct {
fn my_trait_method(&self) -> i32 { self.i }
}
fn takes_trait_object(obj: &dyn MyTrait) -> i32 {
let strong_ref: RefPtr<dyn MyTrait> = RefPtr::new(obj);
strong_ref.my_trait_method()
}
let concrete = make_refptr!(MyStruct { i: 10 });
let i = takes_trait_object(&*concrete);
assert_eq!(i, 10);
依赖项
~1.5MB
~34K SLoC