Restrições Múltiplas
Parte da seção Programação Orientada a Objetos do Journey de Rust da Coddy. Lição 41 de 61.
Às vezes, um único limite de trait não é suficiente. Você pode precisar de um tipo genérico que possa tanto ser impresso quanto fornecer um resumo. Rust permite exigir múltiplos traits usando a sintaxe +.
Veja como especificar que um tipo deve implementar duas traits:
use std::fmt::Display;
trait Summary {
fn summarize(&self) -> String;
}
fn announce<T: Display + Summary>(item: T) {
println!("Breaking news: {}", item);
println!("Summary: {}", item.summarize());
}
O limite T: Display + Summary significa que “T deve implementar tanto Display quanto Summary”. Dentro da função, você pode usar recursos de ambas as traits: imprimir com {} (de Display) e chamar summarize() (de Summary).
Você pode encadear quantas traits forem necessárias:
fn process<T: Display + Summary + Clone>(item: T) {
// Pode imprimir, resumir E clonar
}
Este padrão é essencial quando sua função depende de vários comportamentos. Em vez de aceitar qualquer tipo e esperar que funcione, você declara explicitamente quais recursos são necessários, e o compilador impõe isso em tempo de compilação.
Desafio
FácilVamos criar um sistema de inspeção de produtos que exige que os itens tenham várias capacidades! Você criará uma função genérica que aceita apenas tipos que implementam tanto uma trait personalizada quanto uma trait padrão, demonstrando como a sintaxe + combina vários limites.
Você organizará seu código em dois arquivos:
product.rs: Defina uma trait públicaInspectablecom um método chamadoinspectque recebe&selfe retorna umaStringcontendo os detalhes da inspeção. Em seguida, crie uma struct públicaGadgetcom os campos públicosname(String) eserial(u32). Seu Gadget deve implementar tantoInspectable(retornandoInspecting: {name}) quantostd::fmt::Display(formatando como{name} (SN: {serial})). Por fim, crie uma função genérica pública chamadafull_reportque aceite qualquer tipoTque implemente tantoDisplayquantoInspectable. Essa função deve imprimir duas linhas: primeiro o item usando o formatador{}e, em seguida, o resultado da chamada deinspect().main.rs: Inclua seu módulo de produto e crie uma instância deGadgetusando as entradas fornecidas. Chamefull_reportcom seu gadget para mostrar que ele satisfaz os dois requisitos de trait.
O poder de vários limites é que sua função full_report pode usar capacidades de ambas as traits, exibindo o item de forma adequada E obtendo os detalhes da inspeção, tudo garantido em tempo de compilação.
Sua saída deve mostrar tanto o formato de exibição quanto o resultado da inspeção:
{name} (SN: {serial})
Inspecting: {name}Por exemplo, com as entradas Smartwatch e 98765:
Smartwatch (SN: 98765)
Inspecting: SmartwatchVocê receberá duas entradas: o nome do gadget e o número de série (faça o parse como u32).
Experimente você mesmo
mod product;
use product::{Gadget, full_report};
fn main() {
// Ler entradas
let mut name = String::new();
std::io::stdin().read_line(&mut name).expect("Failed to read line");
let name = name.trim().to_string();
let mut serial_input = String::new();
std::io::stdin().read_line(&mut serial_input).expect("Failed to read line");
let serial: u32 = serial_input.trim().parse().expect("Failed to parse serial");
// TODO: Crie uma instância de Gadget com o name e o serial
// TODO: Chame full_report com o seu gadget
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
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 PlayerPratique por conta própria: Compilador de Rust online