Go não tem Set: por que e como viver sem um conjunto embutido

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

«Onde está meu Set?» — o grito de alma do desenvolvedor Go

\n\n

Se você veio para Go vindo de Python, JavaScript ou Java, mais cedo ou mais tarde se perguntará: «Onde, diabos, está meu amado Set?» — e isso é normal. No Stack Overflow, o tópico «Golang why don't we have a set datastructure» acumulou milhares de visualizações e dezenas de discussões acaloradas. Os desenvolvedores estão acostumados a um conjunto conveniente com elementos únicos, mas Go oferece apenas arrays, slices e maps. Neste artigo, vamos analisar a filosofia dos criadores do Go, aprender a emular um Set e até escrever nossa própria implementação minimalista.

\n\n

Por que os criadores do Go não adicionaram Set à biblioteca padrão?

\n\n

A resposta está no minimalismo e pragmatismo da linguagem. A equipe do Go (Rob Pike, Ken Thompson, Robert Griesemer) seguiu o princípio: «Se algo pode ser feito com uma única construção da linguagem — não crie entidades». Em Go, map não é apenas um dicionário, mas um contêiner universal. Ele já suporta a unicidade das chaves, que é a propriedade principal de um conjunto.

\n\n

Filosofia «menos mágica — mais clareza»

\n\n

Ao contrário do Python, onde set é um tipo separado com seus próprios métodos (.add(), .union()), no Go decidiram não complicar a linguagem. Para que escrever uma estrutura separada se map[T]struct{} faz a mesma coisa? Isso economiza espaço na biblioteca padrão e reduz a barreira de entrada para iniciantes. O principal é aprender a usar corretamente o map como set.

\n\n

Como emular Set em Go: três abordagens práticas

\n\n

Vamos para a prática. Aqui está como implementar um conjunto usando apenas os recursos padrão do Go.

\n\n

1. A mais popular: map[type]struct{}

\n\n

Esta é a abordagem padrão na comunidade Go. Por que struct{}? Porque a estrutura vazia não ocupa memória (0 bytes) — ideal para a marca de «existência» do elemento.

\n\n
package main\n\nimport "fmt"\n\nfunc main() {\n    // Cria um conjunto de números inteiros\n    set := make(map[int]struct{})\n\n    // Adiciona elementos\n    set[1] = struct{}{}\n    set[2] = struct{}{}\n    set[3] = struct{}{}\n    set[1] = struct{}{} // Duplicata é ignorada\n\n    // Verificação de existência\n    if _, exists := set[2]; exists {\n        fmt.Println("2 está no conjunto")\n    }\n\n    // Remoção\n    delete(set, 3)\n\n    // Iteração\n    for key := range set {\n        fmt.Println(key)\n    }\n}
\n\n

Vantagens: alocação de memória zero para valores, simplicidade. Desvantagens: não há métodos .Add() ou .Contains() — tudo é feito através da sintaxe do map.

\n\n

2. Tipo próprio com métodos

\n\n

Se você precisa de uma API limpa, encapsule o map em uma struct:

\n\n
package main\n\nimport "fmt"\n\n// Set — conjunto genérico (Go 1.18+)\ntype Set[T comparable] struct {\n    items map[T]struct{}\n}\n\n// NewSet cria um novo Set\nfunc NewSet[T comparable]() *Set[T] {\n    return &Set[T]{items: make(map[T]struct{})}\n}\n\n// Add adiciona um elemento\nfunc (s *Set[T]) Add(item T) {\n    s.items[item] = struct{}{}\n}\n\n// Contains verifica a presença\nfunc (s *Set[T]) Contains(item T) bool {\n    _, ok := s.items[item]\n    return ok\n}\n\n// Size retorna o tamanho\nfunc (s *Set[T]) Size() int {\n    return len(s.items)\n}\n\nfunc main() {\n    intSet := NewSet[int]()\n    intSet.Add(10)\n    intSet.Add(20)\n    fmt.Println(intSet.Contains(10)) // true\n    fmt.Println(intSet.Size())       // 2\n}
\n\n

Isso já se parece com uma set datastructure em Go completa. Os genéricos (generics) apareceram na versão 1.18, então o código funciona em projetos modernos.

\n\n

3. Uso de bool em vez de struct{}

\n\n

Alguns usam map[T]bool, mas isso gasta 1 byte por valor. Na maioria dos casos, a diferença é imperceptível, mas se você está escrevendo um serviço de alta carga — é melhor usar struct{}.

\n\

Blogs

Book Recommendations