Sprawdzanie, czy mapy są nil
Część sekcji Logika i przepływ sterowania ścieżki GO w Coddy. Lekcja 28 z 68.
W Go mapa może mieć specjalny stan nazywany nil. Mapa nil to w zasadzie niezainicjalizowana mapa, która nie wskazuje na nic w pamięci. Zrozumienie tego pojęcia jest kluczowe, ponieważ próba dodania kluczy do mapy nil spowoduje panikę i awarię programu.
Oto jak powstaje mapa nil i jak wygląda:
var myMap map[string]int
// myMap ma w tym momencie wartość nilGdy deklarujesz zmienną mapy bez jej inicjalizacji, Go automatycznie ustawia ją na nil. Możesz bezpiecznie odczytywać dane z mapy nil (zwróci wartość zerową), ale próba zapisu do niej spowoduje panikę:
// To jest bezpieczne — zwraca 0
value := myMap["key"]
// To spowoduje panikę!
myMap["key"] = 42Aby uniknąć tego problemu, zawsze należy sprawdzić, czy mapa ma wartość nil, zanim spróbuje się dodać do niej klucze. Sprawdzenie jest proste:
if myMap == nil {
myMap = make(map[string]int)
}
myMap["key"] = 42 // Teraz jest to bezpieczneTo proste sprawdzenie gwarantuje, że program nie ulegnie awarii podczas pracy z potencjalnie niezainicjalizowanymi mapami, dzięki czemu kod będzie bardziej odporny i niezawodny.
Wyzwanie
ŁatwyUtwórz bezpieczny system inicjalizacji map, który zapobiega błędom panic dzięki sprawdzaniu, czy mapy mają wartość nil, przed próbą wykonania operacji zapisu. To wyzwanie pokazuje, jak ważne jest sprawdzanie stanu mapy przed wykonaniem operacji, które mogłyby spowodować awarię programu.
Otrzymasz dwa dane wejściowe:
- Ciąg znaków reprezentujący liczbę operacji (np.
"5") - Ciąg znaków zawierający operacje rozdzielone przecinkami. Każda operacja określa nazwę mapy, której dotyczy:
"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"
Twoje zadanie:
- Utwórz dwie zmienne map typu
map[string]into nazwachscoresigrades, nie inicjalizując ich (będą miały wartość nil) - Przetwarzaj kolejno każdą operację z ciągu wejściowego:
- W przypadku operacji
"check":- Sprawdź, czy określona mapa ma wartość nil
- Wypisz
"Map [map_name] is nil", jeśli mapa ma wartość nil - Wypisz
"Map [map_name] is initialized", jeśli mapa nie ma wartości nil
- W przypadku operacji
"init":- Zainicjalizuj określoną mapę za pomocą
make(map[string]int) - Wypisz
"Initialized map [map_name]"
- Zainicjalizuj określoną mapę za pomocą
- W przypadku operacji
"add":- Najpierw sprawdź, czy mapa ma wartość nil
- Jeśli mapa ma wartość nil, wypisz
"Cannot add to nil map [map_name]" - Jeśli mapa nie ma wartości nil, dodaj parę klucz-wartość i wypisz
"Added [key]:[value] to [map_name]"
- Przetwórz operacje, dzieląc ciąg wejściowy:
- Podziel go przy przecinkach, aby uzyskać poszczególne operacje
- W przypadku każdej operacji podziel ją przy dwukropkach, aby uzyskać typ operacji i parametry
- W przypadku operacji add zamień ciąg znaków z wartością na liczbę całkowitą
- Po przetworzeniu wszystkich operacji wyświetl końcowy stan obu map:
- W przypadku każdej mapy, jeśli ma wartość nil:
"Final state - [map_name]: nil" - W przypadku każdej mapy, jeśli jest zainicjalizowana:
"Final state - [map_name]: [count] entries", gdzie count oznacza liczbę par klucz-wartość - Najpierw wypisz
scores, a następniegrades, niezależnie od kolejności, w jakiej operacje ich używały
- W przypadku każdej mapy, jeśli ma wartość nil:
Użyj pakietu strconv, aby zamieniać ciągi znaków z wartościami na liczby całkowite w przypadku operacji add. To wyzwanie pokazuje, jak sprawdzanie, czy mapy mają wartość nil, przed operacjami zapisu zapobiega panikom w czasie działania i sprawia, że Twój kod jest solidny i niezawodny.
Spróbuj swoich sił
package main
import (
"fmt"
"strconv"
"strings"
)
func main() {
// Wczytaj dane wejściowe
var numOpsStr string
var operationsStr string
fmt.Scanln(&numOpsStr)
fmt.Scanln(&operationsStr)
// Zadeklaruj mapy bez inicjalizacji (będą miały wartość nil)
var scores map[string]int
var grades map[string]int
// Podziel operacje według przecinka
operations := strings.Split(operationsStr, ",")
// TODO: Napisz swój kod poniżej
// Przetwarzaj każdą operację po kolei
// Obsłuż operacje "check", "init" i "add"
// W przypadku operacji add użyj strconv.Atoi(), aby przekonwertować ciąg znaków z wartością na liczbę całkowitą
// Wypisz końcowy stan obu map
// Sprawdź, czy mapy mają wartość nil, czy zostały zainicjalizowane, i wypisz odpowiedni wynik
}Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Logika i przepływ sterowania
1Zaawansowane sterowanie przepływem
Instrukcja switch z `fallthrough`Przerywanie zagnieżdżonych pętliKontynuowanie określonej pętliInstrukcja `goto`Podsumowanie — zaawansowane sterowanie pętlami4Projekt: Prosta lista zadań
Konfiguracja projektuDodawanie zadania2Struktury i metody
Definiowanie metod dla strukturOdbiorniki przez wartośćOdbiorniki przez wskaźnikWybór odbiornikówMetody a funkcjePodsumowanie — działanie struktur5Mapy w szczegółach
Mapy strukturWskaźniki jako wartości mapSprawdzanie, czy mapy są nilPorównywanie mapPodsumowanie — licznik częstości słów3Interfejsy (podstawy)
Czym jest interfejs?Definiowanie interfejsuImplementowanie interfejsuUżywanie typów interfejsowychPusty interfejsAsercje typuPrzełącznik typówPodsumowanie – kształty i zachowaniaPoćwicz samodzielnie: Kompilator Go online