Referências Fracas
Weak<T> é uma referência não proprietária a dados Rc/Arc - quebra ciclos via upgrade() para Option<Rc/Arc>.
Receita
use std::rc::{Rc, Weak};
struct Node { value: i32, parent: Option<Weak<Node>>, child: Option<Rc<Node>> }Quando usar: Ponteiros pai em árvores/grafos sem vazar ciclos de Rc.
Exemplo de Funcionamento
use std::rc::{Rc, Weak};
struct Owner { name: String }
struct Observer { owner: Weak<Owner> }
fn main() {
let owner = Rc::new(Owner { name: "app".into() });
let obs = Observer { owner: Rc::downgrade(&owner) };
if let Some(o) = obs.owner.upgrade() {
println!("{}", o.name);
}
}O que isso demonstra:
downgradedeRcparaWeakupgraderetornaNonese o proprietário for descartado- O observador não mantém o proprietário vivo
Mergulho Profundo
Ciclos: A Rc-> B Rc-> A vazam memória. Torne uma direção Weak. Arc::downgrade é o mesmo para threads.
Armadilhas
- Esqueceu a verificação de
upgrade-Nonesignifica que foi descartado. Correção: Trate o proprietário ausente. upgrademantém vivo temporariamente - Descarte oRcdoupgradeprontamente se não for necessário.Weaksemstrong- O valor foi descartado. Correção: Garanta que exista algumstrong.- Padrões
Mutexfracos - Raro - geralmenteArc. upgradeem loop apertado - Custo atômico emArc.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
| Índices em arena | Sem contagem de referência | Precisa da ergonomia do Rc |
| Grafo de propriedade | Propriedade clara da árvore | Ponteiros de volta necessários |
| Eventos de canal | Desacoplar tempos de vida | Observação direta |
FAQs
Weak Send?
Arc::Weak Send+Sync como Arc.strong_count zero?
upgrade None.exemplo de ciclo?
Pai strong filho, filho weak pai.serde weak?
Geralmente pular ou customizado.detectar vazamento de memória?
Apenas ciclos - use weak.downgrade clone?
Clonagem Weak barata.get_mut em Rc?
Apenas se a contagem strong for única.modelo de árvore?
filhos Vec<Rc>, pai Weak.grafo?
Design cuidadoso de ciclos.testar drop?
descartar proprietário, afirmar upgrade None.Relacionado
Versões da Stack: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, e Polars 0.46+.