Проверка карт на nil
Часть раздела Логика и управление потоком путешествия по GO на Coddy. Урок 28 из 68.
В Go карта может иметь особое состояние, называемое nil. Карта nil — это, по сути, неинициализированная карта, которая ни на что не указывает в памяти. Важно понимать эту концепцию, поскольку попытка добавить ключи в карту nil вызовет панику и аварийное завершение программы.
Вот как появляется nil-карта и как она выглядит:
var myMap map[string]int
// На этом этапе myMap равна nilКогда ты объявляешь переменную типа map без инициализации, Go автоматически присваивает ей значение nil. Из nil-карты можно безопасно читать (она вернёт нулевое значение), но попытка записать в неё приведёт к панике:
// Это безопасно — возвращает 0
value := myMap["key"]
// Это вызовет панику!
myMap["key"] = 42Чтобы избежать этой проблемы, перед попыткой добавить ключи в карту всегда проверяй, равна ли она nil. Проверка проста:
if myMap == nil {
myMap = make(map[string]int)
}
myMap["key"] = 42 // Теперь это безопасноЭта простая проверка гарантирует, что ваша программа не завершится с ошибкой при работе с потенциально неинициализированными картами, делая ваш код более надёжным и устойчивым.
Задание
ЛегкоСоздайте безопасную систему инициализации map, которая предотвращает ошибки panic, проверяя, не являются ли map nil, прежде чем пытаться выполнить операции записи. Эта задача демонстрирует критическую важность проверки состояния 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"
Ваша задача:
- Создать две переменные map типа
map[string]intс именамиscoresиgrades, не инициализируя их (они будут nil) - Последовательно обработать каждую операцию из входной строки:
- Для операций
"check":- Проверить, является ли указанная map nil
- Вывести
"Map [map_name] is nil", если map равна nil - Вывести
"Map [map_name] is initialized", если map не равна nil
- Для операций
"init":- Инициализировать указанную map с помощью
make(map[string]int) - Вывести
"Initialized map [map_name]"
- Инициализировать указанную map с помощью
- Для операций
"add":- Сначала проверить, является ли map nil
- Если map равна nil, вывести
"Cannot add to nil map [map_name]" - Если map не равна nil, добавить пару «ключ-значение» и вывести
"Added [key]:[value] to [map_name]"
- Разобрать операции, разделив входную строку:
- Разделить строку по запятым, чтобы получить отдельные операции
- Для каждой операции разделить строку по двоеточиям, чтобы получить тип операции и параметры
- Преобразовать строку со значением в целое число для операций add
- После обработки всех операций вывести конечное состояние обеих map:
- Для каждой map, если она nil:
"Final state - [map_name]: nil" - Для каждой map, если она инициализирована:
"Final state - [map_name]: [count] entries", где count — это количество пар «ключ-значение» - Сначала вывести
scores, а затемgrades, независимо от порядка, в котором операции использовали эти map
- Для каждой map, если она nil:
Используйте пакет strconv, чтобы преобразовывать строки со значениями в целые числа для операций add. Эта задача демонстрирует, как проверка map на nil перед операциями записи предотвращает аварийные завершения во время выполнения и делает ваш код надёжным и устойчивым.
Попробуйте сами
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Сравнение картПовторение — счётчик частоты слов8Проект: простой складской учёт
Обзор проектаПроверка запасов3Интерфейсы (основы)
Что такое интерфейс?Определение интерфейсаРеализация интерфейсаИспользование типов интерфейсовПустой интерфейсУтверждения типовПереключатель типовПовторение — формы и поведениеПотренируйтесь самостоятельно: Онлайн-компилятор Go