Verificando se uma chave existe em um map em Go: guia completo

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

Caça às chaves: como não se perder nos labirintos do map em Go

\n

Imagine: você está escrevendo um microsserviço em Go. Precisa verificar rapidamente se um usuário está registrado no sistema. Você acessa um map, onde a chave é o ID do usuário e o valor é o seu perfil. E surge a pergunta: essa chave existe no map?

\n

Se você vem do Python ou JavaScript, está acostumado a acessar uma chave inexistente e receber uma exceção ou um undefined. Em Go é diferente. Aqui não há exceções, mas existe um mecanismo elegante. E se você tentar ler um valor de uma chave que não existe, o Go não falha, apenas retorna o valor zero para o tipo do valor.

\n

Parece conveniente? Sim, mas também é uma armadilha. Como distinguir a situação "a chave não existe" de "a chave existe, mas o valor é zero"? É para isso que existe uma expressão idiomática especial — o comma ok idiom. Vamos entendê-la de uma vez por todas.

\n\n

Como funciona um map em Go: breve introdução

\n

Antes de mergulharmos nas verificações, vamos lembrar o que é um map em Go. É uma tabela hash que armazena pares chave-valor. Sintaxe de declaração:

\n
// Declarando um map: chaves são strings, valores são inteiros\nvar scores map[string]int\n\n// Inicializando um map vazio (obrigatório!)\nscores = make(map[string]int)\n\n// Ou diretamente com dados\nscores := map[string]int{\n    "Alice": 95,\n    "Bob":   87,\n}
\n

Ponto importante: se você tentar escrever um valor em um map não inicializado (nil map), o programa falhará com pânico. Nunca faça isso!

\n\n

Método principal: atribuição de dois valores (comma ok idiom)

\n

Esta é a maneira mais correta e idiomática de verificar se uma chave existe em um map em Go.

\n

A sintaxe é assim:

\n
value, ok := myMap[key]
\n

Aqui:

\n
    \n
  • value — o valor correspondente à chave (ou o valor zero, se a chave não existir)
  • \n
  • ok — uma variável booleana que é true se a chave existe, e false caso contrário
  • \n
\n

Vamos ver um exemplo completo:

\n
package main\n\nimport "fmt"\n\nfunc main() {\n    // Criando um map com notas de alunos\n    grades := map[string]int{\n        "Maria": 88,\n        "Pedro": 92,\n        "Ana":   0, // Sim, a Ana tem 0 pontos\n    }\n\n    // Verificando a chave "Pedro"\n    if grade, ok := grades["Pedro"]; ok {\n        fmt.Printf("Nota do Pedro: %d\\n", grade)\n    } else {\n        fmt.Println("Pedro não está na lista")\n    }\n\n    // Verificando a chave "João"\n    if grade, ok := grades["João"]; ok {\n        fmt.Printf("Nota do João: %d\\n", grade)\n    } else {\n        fmt.Println("João não está na lista")\n    }\n\n    // Caso complicado: a chave "Ana" existe, mas o valor é 0\n    if grade, ok := grades["Ana"]; ok {\n        fmt.Printf("Nota da Ana: %d\\n", grade) // Vai imprimir: Nota da Ana: 0\n    }\n}
\n

Observe: para a chave "Ana", ok será true, mesmo que o valor seja zero. É por isso que não se pode confiar apenas na verificação do valor!

\n\n

Por que não posso simplesmente comparar com o valor zero?

\n

Muitos iniciantes cometem esse erro. Eles escrevem algo como:

\n
if grades["João"] != 0 {\n    fmt.Println("João está na lista!")\n}
\n

Isso está incorreto por dois motivos:

\n
    \n
  • Para tipos numéricos: se o João realmente tem nota 0, você vai ignorá-lo.
  • \n
  • Para outros tipos: o valor zero pode ser uma string vazia (""), false ou nil. Você não conseguirá distinguir "chave não existe" de "chave existe, mas o valor está vazio".
  • \n
\n

A única maneira confiável é usar o comma ok idiom.

\n\n

Verificando a chave sem obter o valor

\n

Às vezes você só precisa saber se a chave existe, sem se importar com o valor

Blogs

Book Recommendations