Какой правильный умный указатель имеет несколько сильных ссылок и допускает изменчивость?

Я хочу иметь структуру в куче с двумя ссылками; один для меня, а другой от закрытия. Обратите внимание, что код предназначен для однопоточного регистра:

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 сохраняет обратный вызов в каком-то месте, но перед этим может позвонитьcb какneed_callback делает.

Код показывает, чтоstd::rc::Rc не подходит для этой задачи, потому чтоfoo.set_val(x) никогда не вызывается; У меня есть две сильные ссылки иRc::get_mut даетNone в этом случае.

Какой умный указатель с подсчетом ссылок следует использовать вместоstd::rc::Rc чтобы можно было позвонитьfoo.set_val? Может быть, это можно исправить мой код и по-прежнему использоватьstd::rc::Rc?

Подумав, мне нужно что-то вродеstd::rc::Rc, но слабые ссылки должны предотвратить падение. Я могу иметь две слабые ссылки и обновить их до сильных, когда мне нужна изменчивость.

Поскольку это однопоточная программа, я буду иметь только сильные ссылки за раз, поэтому все будет работать, как и ожидалось.

Ответы на вопрос(1)

Ваш ответ на вопрос