Encadeamento de Métodos
Parte da seção Object Oriented Programming do Journey de Rust da Coddy — lição 6 de 61.
Até agora, nossos métodos mutáveis modificaram a struct e não retornaram nada. Mas e se quisermos chamar vários métodos em sequência na mesma instância? Ao retornar uma referência para self, habilitamos o encadeamento de métodos — um padrão onde várias chamadas de método fluem juntas em uma única expressão.
A chave é fazer com que seus métodos &mut self retornem &mut Self:
struct Config {
debug: bool,
timeout: u32,
}
impl Config {
fn new() -> Config {
Config { debug: false, timeout: 30 }
}
fn set_debug(&mut self, value: bool) -> &mut Self {
self.debug = value;
self
}
fn set_timeout(&mut self, seconds: u32) -> &mut Self {
self.timeout = seconds;
self
}
}
Cada método modifica a struct, então retorna self—uma referência mutável de volta para a mesma instância. Isso permite que a próxima chamada de método continue trabalhando nela imediatamente:
fn main() {
let mut config = Config::new();
config.set_debug(true).set_timeout(60);
println!("Debug: {}, Timeout: {}", config.debug, config.timeout);
// Saída: Debug: true, Timeout: 60
}
Em vez de escrever três instruções separadas, configuramos tudo em uma única linha fluida. Este padrão "estilo builder" é especialmente útil ao configurar objetos com muitas configurações opcionais, tornando seu código mais conciso e legível.
Desafio
FácilCrie uma struct TextStyle com três campos: bold (bool), italic (bool), e size (u32).
Adicione um bloco de implementação para TextStyle com o seguinte:
new— uma função associada que retorna umTextStylecombolddefinido comofalse,italicdefinido comofalse, esizedefinido como12set_bold— recebe&mut selfe um valorbool, define o campo bold e retorna&mut Selfpara encadeamento (chaining)set_italic— recebe&mut selfe um valorbool, define o campo italic e retorna&mut Selfpara encadeamento (chaining)set_size— recebe&mut selfe um valoru32, define o campo size e retorna&mut Selfpara encadeamento (chaining)
Você receberá três entradas:
- Primeira linha: configuração de negrito (
trueoufalse) - Segunda linha: configuração de itálico (
trueoufalse) - Terceira linha: tamanho da fonte (u32)
Crie um TextStyle mutável usando new, então use o encadeamento de métodos para aplicar todas as três configurações em uma única expressão. Imprima o estado final no formato mostrado abaixo.
Formato de saída esperado:
Bold: {bold}, Italic: {italic}, Size: {size}Folha de consulta
Métodos que recebem &mut self podem retornar &mut Self para permitir o encadeamento de métodos (method chaining):
impl Config {
fn set_debug(&mut self, value: bool) -> &mut Self {
self.debug = value;
self
}
fn set_timeout(&mut self, seconds: u32) -> &mut Self {
self.timeout = seconds;
self
}
}
Isso permite múltiplas chamadas de método em uma única expressão:
let mut config = Config::new();
config.set_debug(true).set_timeout(60);
Cada método modifica a struct e retorna uma referência mutável para a mesma instância, permitindo que o próximo método continue trabalhando nela imediatamente.
Experimente você mesmo
use std::io;
// TODO: Defina a struct TextStyle aqui
// TODO: Adicione o bloco de implementação para TextStyle com:
// - função associada new()
// - método set_bold()
// - método set_italic()
// - método set_size()
fn main() {
let mut input = String::new();
// Ler configuração de negrito
io::stdin().read_line(&mut input).expect("Failed to read line");
let bold: bool = input.trim().parse().expect("Invalid bool");
input.clear();
// Ler configuração de itálico
io::stdin().read_line(&mut input).expect("Failed to read line");
let italic: bool = input.trim().parse().expect("Invalid bool");
input.clear();
// Ler configuração de tamanho
io::stdin().read_line(&mut input).expect("Failed to read line");
let size: u32 = input.trim().parse().expect("Invalid u32");
// TODO: Crie um TextStyle mutável usando new(), então use o encadeamento de métodos
// para aplicar todas as três configurações em uma única expressão
// TODO: Imprima o resultado no formato: Bold: {bold}, Italic: {italic}, Size: {size}
}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