Fácil Rust

Função genérica para somar dois valores

Enunciado

Escreva uma função genérica somar que recebe dois valores do mesmo tipo e retorna a soma. Use trait bound para permitir apenas tipos que implementem std::ops::Add. Teste com i32 e f64.

Requisitos

  • A função deve se chamar somar e ser genérica.
  • O trait bound deve ser T: std::ops::Add<Output = T>.
  • O programa deve imprimir a soma de dois inteiros e a soma de dois floats.

Código inicial

fn somar<T>(a: T, b: T) -> T {
    // complete aqui
}

fn main() {
    // chame somar com i32 e f64 e imprima
}

Saída esperada

Soma inteiros: 15
Soma floats: 7.5
Ver dica

Use a + b dentro da função. O bound Add<Output = T> garante que o resultado é do mesmo tipo.

Mostrar solução
use std::ops::Add;

// Função genérica que exige que T implemente Add e o resultado seja T
fn somar<T: Add<Output = T>>(a: T, b: T) -> T {
    a + b
}

fn main() {
    let soma_int = somar(10, 5);
    println!("Soma inteiros: {}", soma_int);

    let soma_float = somar(3.5, 4.0);
    println!("Soma floats: {}", soma_float);
}

Passo a passo

  1. Importamos std::ops::Add para usar o trait bound.
  2. Declaramos fn somar<T: Add<Output = T>>(a: T, b: T) -> T. O bound Add<Output = T> diz que T pode ser somado e o resultado é T.
  3. Dentro da função, usamos a + b — o compilador sabe que + está disponível porque T implementa Add.
  4. No main, chamamos somar(10, 5): o compilador infere T = i32.
  5. Chamamos somar(3.5, 4.0): infere T = f64.
  6. A monomorfização gera duas versões da função, uma para cada tipo.

Por que funciona

O trait bound Add<Output = T> é uma promessa de que qualquer tipo T usado terá a operação + definida e retornará T. Isso permite que a função genérica compile sem saber o tipo concreto. Em tempo de compilação, o compilador cria cópias especializadas para i32 e f64, sem custo em runtime.

Erros comuns

  • Esquecer o bound: fn somar<T>(a: T, b: T) -> T { a + b } gera erro "cannot add T to T". Corrija adicionando T: Add<Output = T>.
  • Usar Output = T errado: se escrever T: Add sem especificar Output, o compilador não sabe o tipo do resultado e pode reclamar. Use Add<Output = T>.
  • Tentar somar tipos diferentes: somar(1, 2.0) não compila porque T deve ser o mesmo. Converta explicitamente.

Outra forma de resolver

Poderia usar where:

fn somar<T>(a: T, b: T) -> T
where
    T: Add<Output = T>,
{
    a + b
}

É preferível quando há muitos bounds, pois a assinatura fica mais limpa.

Saída esperada

Soma inteiros: 15
Soma floats: 7.5