Múltiplos Blocos de Implementação
Parte da seção Object Oriented Programming do Journey de Rust da Coddy — lição 5 de 61.
O Rust permite que você divida os métodos de uma struct em múltiplos blocos impl. Embora tudo pudesse ficar em um único bloco, separá-los pode tornar seu código mais organizado e legível.
Aqui está uma struct com sua funcionalidade dividida em dois blocos de implementação:
struct BankAccount {
balance: f64,
}
// Construtor e consultas básicas
impl BankAccount {
fn new(initial: f64) -> BankAccount {
BankAccount { balance: initial }
}
fn balance(&self) -> f64 {
self.balance
}
}
// Métodos de transação
impl BankAccount {
fn deposit(&mut self, amount: f64) {
self.balance += amount;
}
fn withdraw(&mut self, amount: f64) {
self.balance -= amount;
}
}
Ambos os blocos funcionam juntos perfeitamente — o Rust os trata como se fossem um só. Você pode chamar qualquer método, independentemente de em qual bloco ele esteja definido:
fn main() {
let mut account = BankAccount::new(100.0);
account.deposit(50.0);
println!("{}", account.balance()); // 150
}
Este padrão torna-se especialmente útil à medida que suas structs crescem. Você pode agrupar construtores, manter métodos de apenas leitura separados dos que realizam mutações ou organizar por funcionalidade. Não há limite para quantos blocos impl uma struct pode ter.
Desafio
FácilCrie uma struct Player com dois campos: name (String) e score (u32).
Organize os métodos da struct em dois blocos de implementação separados:
Primeiro bloco impl — Construtor e consulta:
new— uma função associada que recebe umname: Stringe retorna umPlayercom oscoredefinido como0get_score— recebe&selfe retorna a pontuação atual comou32
Segundo bloco impl — Modificações de pontuação:
add_points— recebe&mut selfepoints: u32, adiciona os pontos ao scorereset_score— recebe&mut selfe redefine o score para0
Você receberá três entradas:
- Primeira linha: o nome do jogador (String)
- Segunda linha: pontos a adicionar na primeira rodada (u32)
- Terceira linha: pontos a adicionar na segunda rodada (u32)
Crie um jogador usando Player::new, adicione os pontos da primeira rodada, imprima a pontuação, depois resete a pontuação, adicione os pontos da segunda rodada e imprima a pontuação final.
Formato de saída esperado:
{score_after_first_round}
{score_after_reset_and_second_round}Folha de consulta
Rust permite dividir os métodos de uma struct em múltiplos blocos impl para uma melhor organização:
struct BankAccount {
balance: f64,
}
// Primeiro bloco impl
impl BankAccount {
fn new(initial: f64) -> BankAccount {
BankAccount { balance: initial }
}
fn balance(&self) -> f64 {
self.balance
}
}
// Segundo bloco impl
impl BankAccount {
fn deposit(&mut self, amount: f64) {
self.balance += amount;
}
fn withdraw(&mut self, amount: f64) {
self.balance -= amount;
}
}
Todos os métodos de diferentes blocos impl funcionam juntos perfeitamente:
let mut account = BankAccount::new(100.0);
account.deposit(50.0);
println!("{}", account.balance()); // 150
Não há limite para quantos blocos impl uma struct pode ter. Esse padrão é útil para agrupar funcionalidades relacionadas, como separar construtores de métodos de mutação.
Experimente você mesmo
use std::io;
// TODO: Defina a struct Player com os campos name (String) e score (u32)
// TODO: Primeiro bloco impl - Construtor e métodos de consulta (new, get_score)
// TODO: Segundo bloco impl - Métodos de modificação de pontuação (add_points, reset_score)
fn main() {
let mut input = String::new();
// Ler o nome do jogador
io::stdin().read_line(&mut input).expect("Failed to read line");
let name = input.trim().to_string();
// Ler os pontos da primeira rodada
input.clear();
io::stdin().read_line(&mut input).expect("Failed to read line");
let first_round: u32 = input.trim().parse().expect("Invalid number");
// Ler os pontos da segunda rodada
input.clear();
io::stdin().read_line(&mut input).expect("Failed to read line");
let second_round: u32 = input.trim().parse().expect("Invalid number");
// TODO: Criar um jogador usando Player::new
// TODO: Adicionar os pontos da primeira rodada e imprimir a pontuação
// TODO: Resetar a pontuação
// TODO: Adicionar os pontos da segunda rodada e imprimir a pontuação final
}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