Parâmetros opcionais em Go: 5 maneiras práticas (do simples ao avançado)

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

"E onde estão meus parâmetros opcionais?" — o grito de alma do desenvolvedor Go



Você acabou de migrar para Go vindo do Python ou JavaScript e está escrevendo uma função para enviar e-mail. Em Python, seria assim:



def send_email(to, subject, cc=None, bcc=None, attachments=None):    pass


Tudo simples: cc, bcc e attachments são parâmetros opcionais. Você pode não passá-los, e a função funcionará com valores padrão.



Mas eis o problema: em Go não há sobrecarga de métodos nem argumentos nomeados com valores padrão. A comunidade Stack Overflow confirma: a pergunta "Optional Parameters in Go?" acumula milhares de visualizações. É uma dor real para iniciantes.



A boa notícia: em Go existem pelo menos 5 maneiras elegantes de resolver esse problema. Neste artigo, vamos analisar todas elas — das simples às industriais.



Por que o Go é tão "rígido"?



A equipe do Go deliberadamente abriu mão de parâmetros opcionais para:

  • Simplificar a leitura do código — você sempre vê quantos argumentos estão sendo passados para a função.
  • Evitar comportamento mágico — sem valores padrão inesperados.
  • Acelerar a compilação — menos açúcar sintático.


Mas isso não significa que você não possa tornar o código flexível. Vamos ver como contornar as limitações.



Método 1: Funções Variádicas (Variadic Functions) — "barato e eficaz"



A maneira mais simples é usar reticências ... para passar um número variável de argumentos do mesmo tipo.



package main

import "fmt"

// Sum aceita qualquer quantidade de números inteirosfunc Sum(nums ...int) int { total := 0 for _, n := range nums { total += n } return total}

func main() { fmt.Println(Sum(1, 2, 3)) // 6 fmt.Println(Sum(10, 20)) // 30 fmt.Println(Sum()) // 0 — também funciona}


Prós: simplicidade, suporte nativo da linguagem.
Contras: todos os argumentos devem ser do mesmo tipo. Não é possível dizer "passe uma string e depois um int opcional".



Funções variádicas em Go são ótimas para loggers, somadores e qualquer operação onde a quantidade de dados é desconhecida de antemão.



Método 2: Estrutura de Configuração (Configuration Struct) — "quando há muitos parâmetros"



Se você tem mais de 2-3 parâmetros opcionais de tipos diferentes — use uma estrutura.



package main

import "fmt"

type EmailConfig struct { CC []string BCC []string Attachments []string IsHTML bool}

func SendEmail(to, subject, body string, cfg EmailConfig) { fmt.Printf("To: %s, Subject: %s", to, subject) if cfg.IsHTML { fmt.Println("HTML mode enabled") } if len(cfg.CC) > 0 { fmt.Printf("CC: %v", cfg.CC) }}

func main() { // Usando valores padrão (zero values) SendEmail("user@example.com", "Hello", "Body", EmailConfig{})

// Sobrescrevendo alguns campos cfg := EmailConfig{ CC: []string{"boss@example.com"}, IsHTML: true, } SendEmail("user@example.com", "Hello", "Body", cfg)}


Observe: zero values em Go (string vazia, 0, nil para slices) tornam-se valores padrão. Esta é a nossa implementação de parâmetros opcionais em Go através de estruturas.



Prós: legível, tipado, fácil de estender.
Contras: é necessário criar uma estrutura toda vez, mesmo que nada seja alterado.



Método 3: Functional Options Pattern — "o padrão ouro do Go"



Este padrão foi criado por Dave Cheney, um dos principais desenvolvedores do Go. É usado em bibliotecas como gRPC, AWS SDK e na própria biblioteca padrão do Go (por exemplo,

Blogs

Book Recommendations