Argumentos de função padrão em Rust: soluções elegantes sem sobrecarga

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Por que o Rust não tem argumentos padrão — e como contornar isso

\n\n

Se você veio para o Rust do Python, JavaScript ou C++, provavelmente encontrou uma surpresa: o Rust não tem suporte embutido para argumentos padrão. Você não pode simplesmente escrever fn greet(name = "mundo") — o compilador dirá "não".

\n\n

Mas não se preocupe! O Rust oferece outras abordagens, mais flexíveis e seguras. Neste tutorial, vamos analisar 3 maneiras comprovadas de implementar o comportamento de argumentos padrão. Você aprenderá a usar Option<T>, estruturas com configurações e o padrão Builder — e qual método escolher para sua tarefa.

\n\n

O artigo é baseado em uma pergunta real do Stack Overflow (mais de 50.000 visualizações) — adaptamos para um formato educacional. Vamos lá!

\n\n

Método 1. Usando Option<T> — a opção mais simples

\n\n

A maneira mais direta é aceitar argumentos como Option<T> e, dentro da função, substituir pelos valores padrão.

\n\n
fn greet(name: Option<&str>) {\n    let name = name.unwrap_or("mundo");\n    println!("Olá, {}!", name);\n}\n\nfn main() {\n    greet(Some("Ana")); // Olá, Ana!\n    greet(None);         // Olá, mundo!\n}\n
\n\n

Vantagens:

\n
    \n
  • Mínimo de código
  • \n
  • Claro até para iniciantes
  • \n
  • Não requer estruturas adicionais
  • \n
\n\n

Desvantagens:

\n
    \n
  • Cada chamada requer encapsulamento em Some(...) ou None
  • \n
  • Se houver vários parâmetros, o código se torna verboso
  • \n
\n\n

Esta abordagem é ideal para funções com 1-2 parâmetros opcionais. Mas se houver mais, a legibilidade sofre.

\n\n

Método 2. Estrutura com configurações — limpo e escalável

\n\n

Quando os parâmetros se tornam 3, 5 ou 10, uma estrutura de configuração vem em socorro. Você cria um tipo separado que armazena todas as configurações e implementa o trait Default para ele.

\n\n
struct GreetConfig {\n    name: String,\n    greeting: String,\n    excitement_level: u8,\n}\n\nimpl Default for GreetConfig {\n    fn default() -> Self {\n        Self {\n            name: "mundo".to_string(),\n            greeting: "Olá".to_string(),\n            excitement_level: 1,\n        }\n    }\n}\n\nfn greet(config: GreetConfig) {\n    let excitement = "!".repeat(config.excitement_level as usize);\n    println!("{}, {}{}", config.greeting, config.name, excitement);\n}\n\nfn main() {\n    // Usando valores padrão\n    greet(GreetConfig::default());\n    // Saída: Olá, mundo!\n\n    // Alterando apenas o necessário\n    greet(GreetConfig {\n        name: "Ana".to_string(),\n        ..Default::default()\n    });\n    // Saída: Olá, Ana!\n\n    // Chamada totalmente personalizada\n    greet(GreetConfig {\n        name: "Mundo".to_string(),\n        greeting: "Olá".to_string(),\n        excitement_level: 3,\n    });\n    // Saída: Olá, Mundo!!!\n}\n
\n\n

Vantagens:

\n
    \n
  • Máxima flexibilidade
  • \n
  • Você pode adicionar novos campos sem alterar a assinatura da função
  • \n
  • A sintaxe ..Default::default() é muito legível
  • \n
\n\n

Desvantagens:

\n
    \n
  • Requer mais código boilerplate
  • \n
  • Você precisa implementar explicitamente o trait Default
  • \n
\n\n

Esta é a escolha ideal para projetos reais: bibliotecas, funções de configuração, APIs complexas.

\n\n

Método 3. Builder Pattern — para quem gosta de encadeamento

\n\n

O padrão Builder é um clássico do ecossistema Rust. Você cria uma estrutura construtora que acumula parâmetros e, no final, chama o método build().

\n\n
struct Greeter {\n    name: String,\n    greeting: String,\n    excitement_level: u8,\n}\n\nstruct GreeterBuilder {\n    nam                

Blogs

Book Recommendations