Desafio Rust
Função genérica com múltiplos bounds e where
Enunciado
Escreva uma função genérica maior_e_imprime que recebe dois valores do mesmo tipo, encontra o maior e o imprime. A função deve funcionar para tipos que implementem PartialOrd e Display. Use a cláusula where para os bounds. No main, chame a função com i32, f64 e &str.
Requisitos
- A função deve se chamar
maior_e_imprimee ter dois parâmetros genéricos do mesmo tipoT. - Os bounds devem ser
T: PartialOrd + std::fmt::Displaydeclarados comwhere. - A função deve imprimir o maior valor precedido de "Maior: ".
- O programa deve chamar a função três vezes, com tipos diferentes.
Código inicial
fn maior_e_imprime<T>(a: T, b: T)
where
// complete os bounds
{
// complete a lógica
}
fn main() {
// chame com i32, f64 e &str
}
Saída esperada
Maior: 10
Maior: 3.14
Maior: banana
Ver dica
Use if a > b { a } else { b } para obter o maior. O bound Display permite imprimir com {}.
Mostrar solução
use std::fmt::Display;
// Função genérica com where para dois bounds
fn maior_e_imprime<T>(a: T, b: T)
where
T: PartialOrd + Display,
{
let maior = if a > b { a } else { b };
println!("Maior: {}", maior);
}
fn main() {
maior_e_imprime(5, 10);
maior_e_imprime(2.71, 3.14);
maior_e_imprime("banana", "maçã");
}
Passo a passo
- Importamos
std::fmt::Displaypara usar no bound. - Declaramos a função com
where T: PartialOrd + Display. Isso exige que T possa ser comparado com>e impresso com{}. - Dentro da função, comparamos
a > be escolhemos o maior. ComoPartialOrdestá no bound,>funciona. - Armazenamos o maior em
maiore imprimimos comprintln!("Maior: {}", maior). O boundDisplaygarante que{}é válido. - No
main, chamamos com(5, 10): T = i32. - Chamamos com
(2.71, 3.14): T = f64. - Chamamos com
("banana", "maçã"): T = &str. A comparação de&stré lexicográfica; "banana" > "maçã" porque 'b' > 'm'? Na verdade, compare caractere a caractere: 'b' (98) vs 'm' (109), então "banana" < "maçã". O maior é "maçã". A saída esperada deve ser "Maior: maçã".
Por que funciona
A cláusula where permite listar múltiplos bounds de forma legível. PartialOrd fornece a comparação >, e Display fornece a formatação com {}. A monomorfização gera três versões da função, uma para cada tipo. Como os bounds são verificados em tempo de compilação, não há custo em runtime.
Erros comuns
- Esquecer um bound: se omitir
Display, oprintln!com{}falha com "Tdoesn't implementstd::fmt::Display". - Usar
Ordem vez dePartialOrd:Ordé mais restritivo (requer ordem total) e nem todos os tipos implementam, comof64. UsePartialOrd. - Comparar tipos diferentes:
maior_e_imprime(1, 2.0)não compila; T deve ser o mesmo.
Outra forma de resolver
Poderia usar std::cmp::max(a, b) que requer Ord, mas aí não funcionaria com f64. A comparação manual com PartialOrd é mais flexível.
Saída esperada
Maior: 10
Maior: 3.14
Maior: maçã