Verificando Mapas Nil
Parte da seção Lógica & Fluxo do Journey de GO da Coddy — lição 28 de 68.
Em Go, um map pode ter um estado especial chamado nil. Um map nil é essencialmente um map não inicializado que não aponta para nada na memória. Entender esse conceito é crucial porque tentar adicionar chaves a um map nil fará com que seu programa entre em pânico (panic) e encerre inesperadamente.
Veja como um mapa nil ocorre e como ele se parece:
var myMap map[string]int
// myMap é nil neste pontoQuando você declara uma variável de mapa sem inicializá-la, o Go a define automaticamente como nil. Embora você possa ler com segurança de um mapa nil (ele retornará o valor zero), tentar escrever nele causará um pânico (panic):
// Isso é seguro - retorna 0
value := myMap["key"]
// Isso causará um pânico!
myMap["key"] = 42Para evitar este problema, você deve sempre verificar se um mapa é nil antes de tentar adicionar chaves a ele. A verificação é simples:
if myMap == nil {
myMap = make(map[string]int)
}
myMap["key"] = 42 // Agora isso é seguroEsta verificação simples garante que seu programa não falhe ao trabalhar com mapas potencialmente não inicializados, tornando seu código mais robusto e confiável.
Desafio
FácilCrie um sistema de inicialização de mapas seguro que previna erros de pânico (panic) verificando se os mapas são nulos antes de tentar operações de escrita. Este desafio demonstra a importância crítica de validar o estado do mapa antes de realizar operações que poderiam travar seu programa.
Você receberá duas entradas:
- Uma string representando o número de operações (ex:
"5") - Uma string contendo operações no formato:
"operation1:key1:value1,operation2:key2:value2"onde as operações são"check","init", ou"add"(ex:"check:scores,init:scores,add:Alice:95,add:Bob:87,check:grades")
Sua tarefa é:
- Criar duas variáveis de mapa do tipo
map[string]intchamadasscoresegradessem inicializá-las (elas serão nil) - Processar cada operação da string de entrada sequencialmente:
- Para operações
"check":- Verificar se o mapa especificado é nil
- Imprimir
"Map [map_name] is nil"se o mapa for nil - Imprimir
"Map [map_name] is initialized"se o mapa não for nil
- Para operações
"init":- Inicializar o mapa especificado usando
make(map[string]int) - Imprimir
"Initialized map [map_name]"
- Inicializar o mapa especificado usando
- Para operações
"add":- Primeiro verificar se o mapa é nil
- Se o mapa for nil, imprimir
"Cannot add to nil map [map_name]" - Se o mapa não for nil, adicionar o par chave-valor e imprimir
"Added [key]:[value] to [map_name]"
- Analisar as operações dividindo a string de entrada:
- Dividir por vírgulas para obter as operações individuais
- Para cada operação, dividir por dois-pontos para obter o tipo de operação e os parâmetros
- Converter a string de valor para um inteiro para operações de adição
- Após processar todas as operações, exibir o estado final de ambos os mapas:
- Para cada mapa, se for nil:
"Final state - [map_name]: nil" - Para cada mapa, se estiver inicializado:
"Final state - [map_name]: [count] entries"onde count é o número de pares chave-valor
- Para cada mapa, se for nil:
Use o pacote strconv para converter strings de valor em inteiros para operações de adição. Este desafio demonstra como a verificação de mapas nulos antes das operações de escrita evita pânicos em tempo de execução e torna seu código robusto e confiável.
Experimente você mesmo
package main
import (
"fmt"
"strconv"
"strings"
)
func main() {
// Ler entrada
var numOpsStr string
var operationsStr string
fmt.Scanln(&numOpsStr)
fmt.Scanln(&operationsStr)
// Declarar mapas sem inicialização (eles serão nil)
var scores map[string]int
var grades map[string]int
// Dividir operações por vírgula
operations := strings.Split(operationsStr, ",")
// TODO: Escreva seu código abaixo
// Processar cada operação sequencialmente
// Lidar com as operações "check", "init" e "add"
// Para operações add, use strconv.Atoi() para converter a string de valor em inteiro
// Saída do estado final de ambos os mapas
// Verificar se os mapas são nil ou inicializados e imprimir adequadamente
}Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Lógica & Fluxo
1Fluxo de Controle Avançado
Switch com `fallthrough`Interrompendo Loops AninhadosContinuando um Loop EspecíficoA Instrução `goto`Recapitulação - Controle de Loop Avançado4Projeto: Lista de Tarefas Simples
Configuração do ProjetoAdicionando uma Tarefa2Structs e Métodos
Definindo Métodos em StructsRecebedores de ValorRecebedores de PonteiroEscolhendo RecebedoresMétodos vs FunçõesRecapitulação - Comportamento de Structs5Mapas em Profundidade
Mapas de StructsPonteiros como Valores de MapVerificando Mapas NilComparando MapasRecapitulação - Contador de Frequência de Palavras3Interfaces (O Básico)
O que é uma Interface?Definindo uma InterfaceImplementando uma InterfaceUsando Tipos de InterfaceInterface VaziaAsserções de TipoType SwitchRecapitulação - Formas e Comportamentos