0Pricing
Learn Rust Coding · Aula

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 de Cell.
  • set(value): substitui o valor dentro de Cell por 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 um Ref (um ponteiro inteligente imutável). Você pode ter vários empréstimos imutáveis ao mesmo tempo.
  • borrow_mut(): retorna um RefMut (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 implementam Copy. Ele substitui o valor inteiro e geralmente é mais simples e eficiente.
  • RefCell<T>: use para tipos que não implementam Copy. 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 tipos Copy, substitui o valor interno.
  • RefCell<T>: para tipos que não são Copy, fornece referências mutáveis e imutáveis verificadas em tempo de execução.
  • Violar as regras de RefCell leva 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

  1. Ponteiros Inteligentes Box, Rc e Arc
  2. Mutabilidade Interior: RefCell e Cell
  3. Concorrência sem Receios com Threads
← Voltar para Learn Rust Coding