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.