Qual é o ponteiro inteligente certo para ter várias referências fortes e permitir mutabilidade?
Eu quero ter uma estrutura na pilha com duas referências; um para mim e outro de um fechamento. Observe que o código é para o caso de thread único:
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();
}
No código real,need_callback
salva o retorno de chamada em algum lugar, mas antes disso pode chamarcb
Comoneed_callback
faz.
O código mostra questd::rc::Rc
não é adequado para esta tarefa porquefoo.set_val(x)
nunca é chamado; Eu tenho duas referências fortes eRc::get_mut
dáNone
nesse caso.
Que ponteiro inteligente com contagem de referência devo usar em vez destd::rc::Rc
para possibilitar ligarfoo.set_val
? Talvez seja possível corrigir meu código e ainda usarstd::rc::Rc
?
Depois de pensar um pouco, preciso de algo comostd::rc::Rc
, mas referências fracas devem evitar a queda. Posso ter duas referências fracas e atualizá-las para fortes quando preciso de mutabilidade.
Por ser um programa de thread único, terei apenas uma referência forte de cada vez, para que tudo funcione conforme o esperado.