Menu
Coddy logo textTech

Проверка карт на nil

Часть раздела Логика и управление потоком путешествия по GO на Coddy. Урок 28 из 68.

В Go у map может быть специальное состояние, называемое nil. nil map — это по сути неинициализированный map, который ни на что не указывает в памяти. Понимание этой концепции крайне важно, поскольку попытка добавить ключи в nil map приведёт к panic и аварийному завершению программы.

Вот как возникает карта nil и как она выглядит:

var myMap map[string]int
// myMap равен nil на этом этапе

Когда вы объявляете переменную map без инициализации, Go автоматически устанавливает для неё значение nil. Хотя из nil-map можно безопасно читать (она вернёт нулевое значение), попытка записать в неё вызовет панику:

// Это безопасно — возвращает 0
value := myMap["key"]

// Это вызовет панику!
myMap["key"] = 42

Чтобы избежать этой проблемы, всегда выполняй check, является ли map nil, прежде чем пытаться add в него ключи. check прост:

if myMap == nil {
    myMap = make(map[string]int)
}
myMap["key"] = 42 // Теперь это безопасно

Эта простая check гарантирует, что ваша программа не завершится с ошибкой при работе с потенциально неинициализированными maps, делая ваш код более устойчивым и надежным.

challenge icon

Задание

Легко

Создайте безопасную систему инициализации map, которая предотвращает ошибки panic, проверяя nil map перед попыткой выполнения операций записи. Эта задача демонстрирует критическую важность проверки состояния map перед выполнением операций, которые могут привести к сбою программы.

Вы получите два входных значения:

  • Строку, представляющую количество операций (например, "5")
  • Строку, содержащую операции, разделённые запятыми. Каждая операция указывает map, с которым она работает:
    • "check:[map_name]"
    • "init:[map_name]"
    • "add:[map_name]:[key]:[value]"
    Например, "check:scores,init:scores,add:scores:Alice:95,add:scores:Bob:87,check:grades"

Ваша задача:

  1. Создать две переменные map типа map[string]int с именами scores и grades без инициализации (они будут nil)
  2. Обрабатывать каждую операцию из входной строки sequentially:
  3. Для операций "check":
    • Проверить, является ли указанный map nil
    • Вывести "Map [map_name] is nil", если map равен nil
    • Вывести "Map [map_name] is initialized", если map не равен nil
  4. Для операций "init":
    • Инициализировать указанный map с помощью make(map[string]int)
    • Вывести "Initialized map [map_name]"
  5. Для операций "add":
    • Сначала проверить, является ли map nil
    • Если map равен nil, вывести "Cannot add to nil map [map_name]"
    • Если map не равен nil, добавить пару ключ-значение и вывести "Added [key]:[value] to [map_name]"
  6. Разобрать операции, разделив входную строку:
    • Разделить по запятым, чтобы получить отдельные операции
    • Для каждой операции разделить по двоеточиям, чтобы получить тип операции и параметры
    • Преобразовать строку со значением в целое число для операций add
  7. После обработки всех операций отобразить Final состояние обоих map:
    • Для каждого map, если он равен nil: "Final state - [map_name]: nil"
    • Для каждого map, если он инициализирован: "Final state - [map_name]: [count] entries", где count — количество пар ключ-значение
    • Вывести scores первым, а grades вторым, независимо от порядка, в котором они использовались в операциях

Используйте пакет strconv, чтобы преобразовывать строки со значениями в целые числа для операций add. Эта задача демонстрирует, как проверка nil map перед операциями записи предотвращает runtime-панику и делает код надёжным и устойчивым.

Попробуйте сами

package main

import (
	"fmt"
	"strconv"
	"strings"
)

func main() {
	// Прочитать ввод
	var numOpsStr string
	var operationsStr string
	fmt.Scanln(&numOpsStr)
	fmt.Scanln(&operationsStr)
	
	// Объявить maps без инициализации (они будут nil)
	var scores map[string]int
	var grades map[string]int
	
	// Разделить operations по запятой
	operations := strings.Split(operationsStr, ",")
	
	// TODO: Напишите ваш код ниже
	// Обработать каждую операцию последовательно
	// Обработать операции "check", "init" и "add"
	// Для операций add используйте strconv.Atoi() для преобразования строки value в integer
	
	// Вывести конечное состояние обеих maps
	// Проверить, являются ли maps nil или инициализированными, и вывести соответственно
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Логика и управление потоком

Потренируйтесь самостоятельно: Онлайн-компилятор Go