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_imprime e ter dois parâmetros genéricos do mesmo tipo T.
  • Os bounds devem ser T: PartialOrd + std::fmt::Display declarados com where.
  • 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

  1. Importamos std::fmt::Display para usar no bound.
  2. Declaramos a função com where T: PartialOrd + Display. Isso exige que T possa ser comparado com > e impresso com {}.
  3. Dentro da função, comparamos a > b e escolhemos o maior. Como PartialOrd está no bound, > funciona.
  4. Armazenamos o maior em maior e imprimimos com println!("Maior: {}", maior). O bound Display garante que {} é válido.
  5. No main, chamamos com (5, 10): T = i32.
  6. Chamamos com (2.71, 3.14): T = f64.
  7. 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, o println! com {} falha com "T doesn't implement std::fmt::Display".
  • Usar Ord em vez de PartialOrd: Ord é mais restritivo (requer ordem total) e nem todos os tipos implementam, como f64. Use PartialOrd.
  • 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çã