Métodos Mutáveis
Parte da seção Object Oriented Programming do Journey de Rust da Coddy — lição 3 de 61.
Às vezes, os métodos precisam fazer mais do que apenas ler dados — eles precisam alterá-los. Para criar métodos que possam modificar os campos de uma struct, usamos &mut self em vez de &self.
A palavra-chave mut indica um empréstimo (borrow) mutável, dando ao método permissão para alterar o estado interno da instância:
struct Counter {
value: i32,
}
impl Counter {
fn increment(&mut self) {
self.value += 1;
}
fn decrement(&mut self) {
self.value -= 1;
}
fn get(&self) -> i32 {
self.value
}
}
Observe que increment e decrement usam &mut self porque eles modificam value, enquanto get usa &self já que ele apenas lê os dados.
Ao chamar métodos mutáveis, a própria instância deve ser declarada como mutável:
fn main() {
let mut counter = Counter { value: 0 };
counter.increment();
counter.increment();
println!("{}", counter.get()); // 2
counter.decrement();
println!("{}", counter.get()); // 1
}
Se você esquecer a palavra-chave mut ao criar a instância, o Rust impedirá que você chame quaisquer métodos &mut self nela. Isso garante que você esteja sempre ciente de quando seus dados podem mudar.
Desafio
FácilCrie uma struct BankAccount com um único campo: balance (i32).
Adicione um bloco de implementação para BankAccount com três métodos:
deposit— recebe&mut selfe umamount: i32, adiciona o valor ao saldowithdraw— recebe&mut selfe umamount: i32, subtrai o valor do saldoget_balance— recebe&selfe retorna o saldo atual comoi32
Você receberá três entradas:
- Primeira linha: o saldo inicial (i32)
- Segunda linha: o valor do depósito (i32)
- Terceira linha: o valor do saque (i32)
Crie uma instância mutável de BankAccount com o saldo inicial, depois deposite o valor fornecido, saque o valor fornecido e imprima o saldo final.
Formato de saída esperado:
{final_balance}Folha de consulta
Métodos que modificam campos de uma struct usam &mut self (empréstimo mutável), enquanto métodos que apenas leem dados usam &self:
struct Counter {
value: i32,
}
impl Counter {
fn increment(&mut self) {
self.value += 1;
}
fn decrement(&mut self) {
self.value -= 1;
}
fn get(&self) -> i32 {
self.value
}
}
Para chamar métodos mutáveis, a instância deve ser declarada como mutável com let mut:
let mut counter = Counter { value: 0 };
counter.increment();
counter.increment();
println!("{}", counter.get()); // 2
counter.decrement();
println!("{}", counter.get()); // 1
Sem a palavra-chave mut na instância, o Rust impedirá a chamada de quaisquer métodos &mut self.
Experimente você mesmo
use std::io;
// TODO: Defina a struct BankAccount aqui
// TODO: Adicione o bloco de implementação para BankAccount com os métodos deposit, withdraw e get_balance
fn main() {
let mut input = String::new();
// Ler o saldo inicial
io::stdin().read_line(&mut input).expect("Failed to read line");
let initial_balance: i32 = input.trim().parse().expect("Invalid number");
input.clear();
// Ler o valor do depósito
io::stdin().read_line(&mut input).expect("Failed to read line");
let deposit_amount: i32 = input.trim().parse().expect("Invalid number");
input.clear();
// Ler o valor do saque
io::stdin().read_line(&mut input).expect("Failed to read line");
let withdraw_amount: i32 = input.trim().parse().expect("Invalid number");
// TODO: Criar uma instância mutável de BankAccount com initial_balance
// TODO: Chamar deposit com deposit_amount
// TODO: Chamar withdraw com withdraw_amount
// TODO: Imprimir o saldo final usando get_balance
}Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Object Oriented Programming
1Métodos e Comportamento
Introdução a Blocos de ImplementaçãoO Parâmetro SelfMétodos MutáveisFunções AssociadasMúltiplos Blocos de ImplementaçãoEncadeamento de MétodosRecapitulação - Ações de Retângulo4Projeto: Pet Virtual
Definindo o PetAlimentando o Pet7Traits Padrão
A Trait DebugA Trait DisplayClone e CopyTraits de IgualdadeRecapitulação - Ponto Imprimível10Projeto: Sistema de Documentos
A Trait DrawComponente de Texto2Encapsulamento e Módulos
Fundamentos de MódulosA Palavra-chave PublicCampos PrivadosGettersSettersRecapitulação - Cofre Seguro5Genéricos
Structs GenéricasMétodos GenéricosMúltiplos Tipos GenéricosFunções GenéricasRecapitulação - Ponto de Coordenada8Traits como Restrições
Sintaxe de Restrições de TraitRestrições MúltiplasA Cláusula WhereRetornando Tipos com TraitsRecapitulação - Impressora Genérica11Padrões de Projeto em Rust
Padrão NewtypeComposiçãoA Trait DropFrom e IntoRecapitulação - Mock de Smart Pointer3Enums Avançados
Enums com DadosMétodos em EnumsCorrespondência de Variantes de DadosO Enum Option RevisitadoRecapitulação - Enum Shape6Definição de Traits
O que é uma Trait?Implementando TraitsImplementações PadrãoSobrescrevendo PadrõesTraits com ParâmetrosRecapitulação - Media Player