בדיקה אם מפות הן nil
חלק מהיחידה לוגיקה וזרימת התוכנית במסלול ה-GO של Coddy. שיעור 28 מתוך 68.
ב-Go, למפה יכול להיות מצב מיוחד שנקרא nil. מפה מסוג nil היא למעשה מפה שלא אותחלה ושאינה מצביעה לשום דבר בזיכרון. חשוב להבין את המושג הזה, כי ניסיון להוסיף מפתחות למפה מסוג nil יגרום לתוכנית שלך להיכנס למצב panic ולקרוס.
כך נראית מפה מסוג nil כשהיא מתרחשת:
var myMap map[string]int
// בשלב זה myMap הוא nilכשמצהירים על משתנה מסוג מפה בלי לאתחל אותו, Go מאתחלת אותו אוטומטית ל־nil. אפשר לקרוא בבטחה ממפה מסוג nil (היא תחזיר את ערך האפס), אבל ניסיון לכתוב אליה יגרום ל־panic:
// זה בטוח - מחזיר 0
value := myMap["key"]
// זה יגרום ל-panic!
myMap["key"] = 42כדי להימנע מהבעיה הזאת, עליך לבדוק תמיד אם המפה היא nil לפני שמנסים להוסיף לה מפתחות. הבדיקה פשוטה:
if myMap == nil {
myMap = make(map[string]int)
}
myMap["key"] = 42 // עכשיו זה בטוחהבדיקה הפשוטה הזו מבטיחה שהתוכנית שלך לא תקרוס כשעובדים עם מפות שעשויות לא להיות מאותחלות, וכך הקוד שלך יהיה חסין ואמין יותר.
אתגר
קלצרו מערכת בטוחה לאתחול מפות, שמונעת שגיאות panic באמצעות בדיקה אם המפות הן nil לפני ניסיון לבצע פעולות כתיבה. אתגר זה מדגים את החשיבות הקריטית של אימות מצב המפה לפני ביצוע פעולות שעלולות לגרום לקריסת התוכנית.
תקבלו שתי קלטים:
- מחרוזת שמייצגת את מספר הפעולות (למשל,
"5") - מחרוזת שמכילה פעולות המופרדות בפסיקים. בכל פעולה מצוין שם המפה שעליה היא פועלת:
"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[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]"
- לנתח את הפעולות באמצעות פיצול מחרוזת הקלט:
- לפצל לפי פסיקים כדי לקבל את הפעולות הבודדות
- עבור כל פעולה, לפצל לפי נקודתיים כדי לקבל את סוג הפעולה ואת הפרמטרים
- להמיר את מחרוזת הערך למספר שלם עבור פעולות add
- לאחר עיבוד כל הפעולות, להציג את המצב הסופי של שתי המפות:
- עבור כל מפה, אם היא nil:
"Final state - [map_name]: nil" - עבור כל מפה, אם היא מאותחלת:
"Final state - [map_name]: [count] entries"כאשר count הוא מספר צמדי המפתח-ערך - להדפיס תחילה את
scoresולאחר מכן אתgrades, ללא קשר לסדר שבו הפעולות השתמשו בהן
- עבור כל מפה, אם היא nil:
השתמשו בחבילה strconv כדי להמיר מחרוזות של ערכים למספרים שלמים עבור פעולות add. אתגר זה מדגים כיצד בדיקה אם המפות הן nil לפני פעולות כתיבה מונעת שגיאות panic בזמן ריצה והופכת את הקוד שלכם לחסין ואמין.
נסו בעצמכם
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מפות לעומק
מפות של Structsמצביעים כערכים במפהבדיקה אם מפות הן nilהשוואת מפותסיכום - מונה תדירות מילים8פרויקט: ניהול מלאי פשוט
סקירת הפרויקטבדיקת המלאיתרגלו בעצמכם: קומפיילר Go אונליין