RefCell & Cell
Cell<T> para valores Copy sem rastreamento de empréstimo. RefCell<T> aplica em tempo de execução as regras de & / &mut para dados não-Copy.
Receita
use std::cell::Cell;
fn main() {
let c = Cell::new(0);
c.set(c.get() + 1);
println!("{}", c.get());
}Quando usar isso: Modificar através de um handle compartilhado em código single-thread quando o borrow checker impede.
Exemplo Funcionando
use std::cell::RefCell;
struct Cache {
hits: RefCell<u32>,
}
impl Cache {
fn hit(&self) {
*self.hits.borrow_mut() += 1;
}
fn hits(&self) -> u32 {
*self.hits.borrow()
}
}
fn main() {
let c = Cache { hits: RefCell::new(0) };
c.hit();
println!("{}", c.hits());
}O que isso demonstra:
- Métodos
&selfmodificando o interior viaRefCell - Verificações em tempo de execução de
borrow/borrow_mut - Pânico em
borrow_mutduplo
Mergulho Profundo
try_borrow para não causar pânico. Ref/RefMut guardam o dereferenciamento para o interior. Não é Sync - thread única.
Armadilhas
- Pânico em empréstimo reentrante - Conflito de empréstimo em tempo de execução. Correção: Empréstimos mais curtos, reestruturar.
- RefCell entre threads - Não é
Sync. Correção:Mutex. - Cell para não-Copy - Use
RefCellouUnsafeCell(unsafe). - Manter RefMut por muito tempo - Bloqueia outros empréstimos. Correção: Limites de escopo.
- RefCell como primeira escolha - Tente empréstimos em tempo de compilação primeiro.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
Mutex | Threads | Single-threaded |
Atomic* | Flags de inteiros | Tipos complexos |
Campos divididos &mut | Compilação OK | Handle compartilhado necessário |
FAQs
Cell get set?
Apenas cópia.replace take?
RefCell::replace troca o valor.as_ptr unsafe?
Escape hatch avançado.map splitted?
RefCell mapeia partes do empréstimo separadamente - API cuidadosa.try_borrow_mut?
Retorna Result em conflito.RefCell em Rc?
Padrão comum.lint?
cuidado com refcell em async.Cell bool?
Flags em tempo de execução sem o overhead do RefCell.UnsafeCell?
Interior unsafe - blocos de construção.test panic borrow?
should_panic mutação dupla.Relacionados
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+.