Mutabilidade Interior: RefCell e Cell
Aprenda sobre `RefCell` e `Cell` para obter mutabilidade interior, permitindo aceder a dados de forma mutável através de uma referência imutável, com segurança.
Mutabilidade Interior: RefCell e Cell é uma aula grátis de Learn Rust Coding no CoddyKit. Esta é a aula 2 de 3. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Learn Rust Coding, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Learn Rust Coding inclui 3 aulas no total.
O que é mutabilidade interior?
No Rust, as regras de empréstimo normalmente impedem que você tenha uma referência mutável para dados quando já tem uma referência imutável a eles. Isso garante a segurança dos dados.
Mutabilidade interior é um padrão de projeto que permite modificar dados mesmo quando você tem apenas uma referência imutável a eles. É como uma exceção controlada às regras usuais do Rust, usada em situações específicas.
`Cell<T>`: para tipos Copy
O tipo Cell<T> fornece mutabilidade interior para tipos que implementam o traço Copy (como inteiros, valores booleanos e caracteres). Ele funciona substituindo o valor armazenado.
get(): retorna uma cópia do valor dentro deCell.set(value): substitui o valor dentro deCellpor um novo.
É simples e eficiente para dados pequenos que podem ser copiados.
Usando `Cell` para atualizar valores
Aqui está um exemplo básico de Cell. Observe como podemos alterar o valor dentro de Cell, embora o próprio Cell seja declarado como imutável.
use std::cell::Cell;
fn main() {
let my_num = Cell::new(10);
println!("Initial value: {}", my_num.get());
my_num.set(20);
println!("Updated value: {}", my_num.get());
let x = &my_num;
x.set(30); // Still works via immutable reference!
println!("Via immutable ref: {}", my_num.get());
}`RefCell<T>`: para tipos que não são Copy
Quando você precisa de mutabilidade interior para tipos que não implementam Copy (como String, Vec ou estruturas personalizadas), use RefCell<T>.
RefCell permite obter referências mutáveis aos dados internos, mas aplica as regras de empréstimo do Rust em tempo de execução, não em tempo de compilação.
Empréstimos em tempo de execução de `RefCell`
RefCell fornece métodos que retornam ponteiros inteligentes:
borrow(): retorna umRef(um ponteiro inteligente imutável). Você pode ter vários empréstimos imutáveis ao mesmo tempo.borrow_mut(): retorna umRefMut(um ponteiro inteligente mutável). Você pode ter apenas um empréstimo mutável por vez.
Se você violar essas regras em tempo de execução, seu programa entrará em panic!.
Usando `RefCell` (empréstimo imutável)
Aqui, usamos borrow() para obter uma referência imutável à String dentro de RefCell. Podemos imprimir seu conteúdo.
use std::cell::RefCell;
fn main() {
let my_string_cell = RefCell::new(String::from("Hello"));
let s1 = my_string_cell.borrow();
println!("Value: {}", *s1); // Dereference Ref to get String
let s2 = my_string_cell.borrow(); // Multiple immutable borrows are fine
println!("Another value: {}", *s2);
}Usando `RefCell` (empréstimo mutável)
Agora, vamos obter uma referência mutável usando borrow_mut(). Isso nos permite modificar a String. Observe que, quando s_mut está no escopo, nenhum outro empréstimo (mutável ou imutável) é permitido.
use std::cell::RefCell;
fn main() {
let my_string_cell = RefCell::new(String::from("World"));
{ // Scope for the mutable borrow
let mut s_mut = my_string_cell.borrow_mut();
s_mut.push_str(", Rust!");
}
// s_mut is out of scope here, so we can borrow again
let s_final = my_string_cell.borrow();
println!("Final value: {}", *s_final);
}O panic em tempo de execução de `RefCell`
Se você tentar obter um empréstimo mutável enquanto outro empréstimo mutável (ou qualquer empréstimo imutável) estiver ativo, RefCell fará seu programa entrar em panic! durante a execução. Isso evita a corrupção dos dados.
Execute este código para ver isso em ação! Ele falhará com um erro de "empréstimo já em uso".
use std::cell::RefCell;
fn main() {
let my_value = RefCell::new(vec![1, 2, 3]);
let _first_mut_borrow = my_value.borrow_mut();
println!("First mutable borrow is active.");
// This line will cause a runtime panic!
// Try commenting it out to see the program run successfully.
let _second_mut_borrow = my_value.borrow_mut();
println!("This line will not be reached.");
}Resumo: `Cell` vs. `RefCell`
A escolha entre Cell e RefCell depende do seu tipo de dado e de como você precisa interagir com ele:
Cell<T>: use para tipos que implementamCopy. Ele substitui o valor inteiro e geralmente é mais simples e eficiente.RefCell<T>: use para tipos que não implementamCopy. Ele fornece referências aos dados internos e aplica as regras de empréstimo em tempo de execução, permitindo mutações mais complexas.
Verificação rápida: Cell ou RefCell?
Você tem uma struct que precisa armazenar um contador mutável (u32) e uma lista mutável de nomes (Vec<String>), e ambos precisam ser atualizados por meio de uma referência imutável à struct. Quais tipos de mutabilidade interior você usaria para cada campo?
Recapitulação: mutabilidade interior
Você aprendeu sobre o padrão de mutabilidade interior do Rust, que permite modificar dados por meio de uma referência imutável de forma controlada e segura.
Cell<T>: para tiposCopy, substitui o valor interno.RefCell<T>: para tipos que não sãoCopy, fornece referências mutáveis e imutáveis verificadas em tempo de execução.- Violar as regras de
RefCellleva a um panic em tempo de execução, garantindo a segurança.
Esses tipos são essenciais para padrões como objetos simulados, referências circulares ou situações em que uma referência imutável compartilhada precisa acompanhar o estado interno.
Perguntas Frequentes
A aula “Mutabilidade Interior: RefCell e Cell” é grátis?
Sim — o texto completo de “Mutabilidade Interior: RefCell e Cell” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Learn Rust Coding, atualize para CoddyKit PRO. O curso de Learn Rust Coding inclui 3 aulas no total.
O que vou aprender em “Mutabilidade Interior: RefCell e Cell”?
Aprenda sobre `RefCell` e `Cell` para obter mutabilidade interior, permitindo aceder a dados de forma mutável através de uma referência imutável, com segurança. Você pratica Learn Rust Coding com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Learn Rust Coding?
Nenhuma experiência prévia é necessária. Learn Rust Coding no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 3.
Quanto tempo leva a aula “Mutabilidade Interior: RefCell e Cell”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Learn Rust Coding?
Sim. Cada aula de Learn Rust Coding inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Ponteiros Inteligentes Box, Rc e Arc
- Mutabilidade Interior: RefCell e Cell
- Concorrência sem Receios com Threads