0Pricing
Learn Rust Coding · Aula

Funções genéricas

Parametrize o comportamento pelo tipo.

Funções genéricas é uma aula grátis de Learn Rust Coding no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Learn Rust Coding, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Learn Rust Coding inclui 4 aulas no total.

Por que usar funções genéricas

Funções genéricas permitem escrever uma única função que funciona com vários tipos, em vez de copiar o código para cada tipo. Rust substitui o tipo substituto em tempo de compilação.

Imagine escrever uma função largest para inteiros e outra para chars. Os genéricos transformam essas duas funções em uma única definição, sem custo em tempo de execução.

Parâmetros de tipo

Uma função genérica declara um parâmetro de tipo entre sinais de menor e maior após o nome. O nome T é uma convenção, mas qualquer identificador CamelCase funciona.

O parâmetro pode aparecer nos argumentos e no tipo de retorno, representando o tipo concreto usado por quem chama a função.

fn first<T>(pair: (T, T)) -> T {
    pair.0
}

Uma Função de Identidade Simples

Este programa define uma função genérica echo que retorna seu argumento sem alterações. Ela é chamada uma vez com um inteiro e outra vez com uma fatia de texto.

O compilador gera uma versão concreta separada para cada tipo que é realmente utilizado.

fn echo<T>(value: T) -> T {
    value
}

fn main() {
    println!("{}", echo(42));
    println!("{}", echo("hi"));
}

Monomorfização

Rust usa monomorfização: no momento da compilação, produz uma cópia especializada da função para cada tipo concreto utilizado. Não há encaixotamento nem despacho virtual.

O resultado é um código genérico que executa tão rapidamente quanto um código específico para cada tipo, escrito manualmente.

Genéricos Precisam de Restrições

Dentro de uma função genérica, só é possível usar operações compatíveis com todos os tipos possíveis. Um T sem restrições não pode ser somado, comparado ou impresso.

Este código falha na compilação porque talvez T não implemente comparação. A seguir, vamos corrigi-lo com uma restrição de característica.

fn larger<T>(a: T, b: T) -> T {
    if a > b { a } else { b }
}

Adicionando uma Restrição de Característica

Para comparar valores, restringimos T com PartialOrd. A restrição garante que o tipo é compatível com o operador >.

Também adicionamos Copy para que os valores possam ser retornados sem problemas de movimentação em tipos simples, como inteiros.

fn larger<T: PartialOrd + Copy>(a: T, b: T) -> T {
    if a > b { a } else { b }
}

Chamando a Função com Restrições

Agora a função funciona para qualquer tipo que implemente ambas as características. Inteiros e números de ponto flutuante satisfazem PartialOrd + Copy.

O mesmo código-fonte, monomorfizado em duas versões, imprime os resultados de cada chamada.

fn larger<T: PartialOrd + Copy>(a: T, b: T) -> T {
    if a > b { a } else { b }
}

fn main() {
    println!("{}", larger(3, 9));
    println!("{}", larger(2.5, 1.0));
}

Vários Parâmetros de Tipo

Uma função pode declarar vários parâmetros de tipo. Cada um é independente, portanto os dois argumentos podem ter tipos diferentes.

Aqui, pair aceita qualquer T e qualquer U, retornando-os como uma tupla.

fn pair<T, U>(a: T, b: U) -> (T, U) {
    (a, b)
}

Imprimindo Valores Genéricos

Para imprimir um valor genérico com {}, o tipo precisa implementar Display. Adicionamos essa restrição para que qualquer tipo imprimível possa ser passado.

Isso associa um rótulo a um valor e o retorna, demonstrando uma restrição usada exclusivamente para formatação.

use std::fmt::Display;

fn announce<T: Display>(label: &str, value: T) {
    println!("{}: {}", label, value);
}

fn main() {
    announce("count", 7);
    announce("name", "Ada");
}

Sintaxe Turbofish

Às vezes, o compilador não consegue inferir T apenas pelos argumentos. O turbofish ::<Type> permite especificá-lo explicitamente no local da chamada.

Ele é mais comum em métodos como parse e collect, nos quais o tipo de retorno é ambíguo.

fn main() {
    let n = "42".parse::<i32>().unwrap();
    println!("{}", n + 1);
}

Genéricos com Referências

Parâmetros genéricos também funcionam com referências. Restringir por referência evita exigir Copy quando você só precisa ler os valores.

Este auxiliar no estilo de longest_str empresta duas fatias e retorna uma delas sem assumir a propriedade.

fn pick<'a, T: PartialOrd>(a: &'a T, b: &'a T) -> &'a T {
    if a > b { a } else { b }
}

Verificação Rápida

Teste sua compreensão sobre funções genéricas em Rust.

Recapitulação

Funções genéricas usam parâmetros de tipo entre sinais de menor e maior para funcionar com muitos tipos, sem custo em tempo de execução graças à monomorfização.

Operações sobre um tipo genérico exigem restrições de características, como PartialOrd, Copy ou Display. Use o turbofish quando a inferência não puder determinar o tipo.

Perguntas Frequentes

A aula “Funções genéricas” é grátis?

Sim — o texto completo de “Funções genéricas” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Learn Rust Coding, atualize para CoddyKit PRO. O curso de Learn Rust Coding inclui 4 aulas no total.

O que vou aprender em “Funções genéricas”?

Parametrize o comportamento pelo tipo. Você pratica Learn Rust Coding com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Learn Rust Coding?

Nenhuma experiência prévia é necessária. Learn Rust Coding no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.

Quanto tempo leva a aula “Funções genéricas”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Learn Rust Coding?

Sim. Cada aula de Learn Rust Coding inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Funções genéricas
  2. Structs e enums genéricos
  3. Limites de traits
  4. Cláusulas where e múltiplos limites
← Voltar para Learn Rust Coding