【发布时间】:2016-08-21 14:21:23
【问题描述】:
我想在堆上有一个带有两个引用的结构;一个给我,另一个来自关闭。注意代码是针对单线程情况的:
use std::rc::Rc;
#[derive(Debug)]
struct Foo {
val: u32,
}
impl Foo {
fn set_val(&mut self, val: u32) {
self.val = val;
}
}
impl Drop for Foo {
fn drop(&mut self) {
println!("we drop {:?}", self);
}
}
fn need_callback(mut cb: Box<FnMut(u32)>) {
cb(17);
}
fn create() -> Rc<Foo> {
let rc = Rc::new(Foo { val: 5 });
let weak_rc = Rc::downgrade(&rc);
need_callback(Box::new(move |x| {
if let Some(mut rc) = weak_rc.upgrade() {
if let Some(foo) = Rc::get_mut(&mut rc) {
foo.set_val(x);
}
}
}));
rc
}
fn main() {
create();
}
在实际代码中,need_callback 将回调保存到某个位置,但在此之前可能会像 need_callback 那样调用 cb。
代码显示std::rc::Rc不适合这个任务,因为foo.set_val(x)从未被调用过;我有两个强引用,Rc::get_mut 在这种情况下给出了None。
我应该使用什么具有引用计数的智能指针而不是std::rc::Rc 才能调用foo.set_val?也许可以修复我的代码并仍然使用std::rc::Rc?
经过一番思考,我需要std::rc::Rc 之类的东西,但弱引用应该防止丢弃。我可以有两个弱引用,并在需要可变性时将它们升级为强引用。
因为它是一个单线程程序,我一次只有强引用,所以一切都会按预期工作。
【问题讨论】:
标签: rust smart-pointers