Проверка карт на nil
Часть раздела Логика и управление потоком путешествия по GO на Coddy — урок 28 из 68.
В Go карта (map) может находиться в специальном состоянии, называемом nil. Карта nil — это, по сути, неинициализированная карта, которая ни на что не указывает в памяти. Понимание этой концепции крайне важно, так как попытка добавить ключи в карту nil приведет к панике и аварийному завершению вашей программы.
Вот как возникает карта nil и как она выглядит:
var myMap map[string]int
// на данном этапе myMap равна nilКогда вы объявляете переменную карты (map) без её инициализации, Go автоматически устанавливает её в nil. Хотя вы можете безопасно читать из nil карты (она вернет нулевое значение), попытка записи в неё вызовет панику (panic):
// Это безопасно - возвращает 0
value := myMap["key"]
// Это вызовет панику!
myMap["key"] = 42Чтобы избежать этой проблемы, вам всегда следует проверять, является ли карта nil перед попыткой добавить в неё ключи. Проверка проста:
if myMap == nil {
myMap = make(map[string]int)
}
myMap["key"] = 42 // Теперь это безопасноЭта простая проверка гарантирует, что ваша программа не завершится аварийно при работе с потенциально неинициализированными картами, что делает ваш код более устойчивым и надежным.
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Задание
ЛегкоСоздайте систему безопасной инициализации карт, которая предотвращает ошибки паники, проверяя карты на nil перед попыткой выполнения операций записи. Эта задача демонстрирует критическую важность проверки состояния карты перед выполнением операций, которые могут привести к сбою вашей программы.
Вы получите два входных значения:
- Строка, представляющая количество операций (например,
"5") - Строка, содержащая операции в формате:
"operation1:key1:value1,operation2:key2:value2", где операции могут быть"check","init"или"add"(например,"check:scores,init:scores,add:Alice:95,add:Bob:87,check:grades")
Ваша задача:
- Создать две переменные карт типа
map[string]intс именамиscoresиgradesбез их инициализации (они будут nil) - Последовательно обработать каждую операцию из входной строки:
- Для операций
"check":- Проверить, является ли указанная карта nil
- Вывести
"Map [map_name] is nil", если карта nil - Вывести
"Map [map_name] is initialized", если карта не nil
- Для операций
"init":- Инициализировать указанную карту с помощью
make(map[string]int) - Вывести
"Initialized map [map_name]"
- Инициализировать указанную карту с помощью
- Для операций
"add":- Сначала проверить, является ли карта nil
- Если карта nil, вывести
"Cannot add to nil map [map_name]" - Если карта не nil, добавить пару ключ-значение и вывести
"Added [key]:[value] to [map_name]"
- Разобрать операции, разделив входную строку:
- Разделить по запятым, чтобы получить отдельные операции
- Для каждой операции разделить по двоеточиям, чтобы получить тип операции и параметры
- Преобразовать строку значения в целое число для операций добавления
- После обработки всех операций отобразить конечное состояние обеих карт:
- Для каждой карты, если она nil:
"Final state - [map_name]: nil" - Для каждой карты, если она инициализирована:
"Final state - [map_name]: [count] entries", где count — количество пар ключ-значение
- Для каждой карты, если она nil:
Используйте пакет strconv для преобразования строк значений в целые числа для операций добавления. Эта задача демонстрирует, как проверка карт на nil перед операциями записи предотвращает панику во время выполнения и делает ваш код надежным и стабильным.
Шпаргалка
Карта nil — это неинициализированная карта, которая ни на что не указывает в памяти. Попытка добавить ключи в карту nil приведет к панике и аварийному завершению вашей программы.
Объявление карты без её инициализации создает карту nil:
var myMap map[string]int
// на данном этапе myMap равна nilЧтение из карты nil безопасно (возвращает нулевое значение), но запись в неё вызовет панику:
// Это безопасно — возвращает 0
value := myMap["key"]
// Это вызовет панику!
myMap["key"] = 42Всегда проверяйте, не является ли карта nil, перед добавлением ключей:
if myMap == nil {
myMap = make(map[string]int)
}
myMap["key"] = 42 // Теперь это безопасноПопробуйте сами
package main
import (
"fmt"
"strconv"
"strings"
)
func main() {
// Чтение входных данных
var numOpsStr string
var operationsStr string
fmt.Scanln(&numOpsStr)
fmt.Scanln(&operationsStr)
// Объявление мап без инициализации (они будут nil)
var scores map[string]int
var grades map[string]int
// Разделение операций по запятой
operations := strings.Split(operationsStr, ",")
// TODO: Напишите свой код ниже
// Обработка каждой операции последовательно
// Обработка операций "check", "init" и "add"
// Для операций add используйте strconv.Atoi() для преобразования строкового значения в целое число
// Вывод финального состояния обеих мап
// Проверка, являются ли мапы nil или инициализированными, и соответствующий вывод
}В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Продвинутое управление потоком выполнения
Switch с использованием `fallthrough`Выход из вложенных цикловПродолжение конкретного циклаОператор `goto`Итоги: Продвинутое управление циклами4Проект: Простой список задач
Настройка проектаДобавление задачи2Структуры и методы
Определение методов для структурПолучатели по значениюПолучатели по указателюВыбор типа получателяМетоды против функцийИтоги: поведение структур5Карты: подробный разбор
Карты структурУказатели как значения картПроверка карт на nilСравнение картИтоги: счетчик частоты слов3Интерфейсы (Основы)
Что такое интерфейс?Определение интерфейсаРеализация интерфейсаИспользование интерфейсных типовПустой интерфейсУтверждение типаПереключатель типовИтоги: Фигуры и поведение