האופרטורים ? ו-!
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Dart של Coddy. שיעור 25 מתוך 110.
בעבודה עם טיפוסים שיכולים להיות ריקים, Dart מספקת שני אופרטורים חיוניים לגישה בטוחה לערכים. אופרטור גישה מודע ל־null ?. ואופרטור הצהרה על אי־ריקות ! מאפשרים לך לשלוט באופן שבו תטפל בערכים שעשויים להיות null.
האופרטור ?. ניגש בבטחה למאפיינים או למתודות של ערך שניתן להיות null. אם הערך הוא null, הביטוי כולו מחזיר null במקום לקרוס:
String? name = 'Alice';
print(name?.length); // 5
name = null;
print(name?.length); // null (בלי קריסה!)האופרטור ! אומר ל-Dart: "אני בטוח שהערך הזה אינו null." הוא ממיר טיפוס שניתן להיות null לטיפוס שלא ניתן להיות null, אך זורק שגיאה אם הערך אכן null:
String? maybeName = 'Bob';
String definite = maybeName!; // תקין - אנו קובעים שהוא אינו null
print(definite.length); // 3
String? empty = null;
// String crash = empty!; // שגיאת זמן ריצה! הערך היה nullהשתמשו ב־?. כשרוצים לטפל בערכי null בצורה בטוחה. השתמשו ב־! רק כשאתם בטוחים לחלוטין שערך קיים — אולי לאחר שבדקתם זאת באמצעות הצהרת if או כשידוע לכם שהלוגיקה מבטיחה ערך. שימוש מופרז ב־! מבטל את המטרה של בטיחות מפני null ועלול לגרום לקריסות בזמן ריצה.
אתגר
קלבואו נבנה מערכת מלאי מוצרים שמדגימה איך לעבוד בבטחה עם ערכים שיכולים להיות null באמצעות האופרטורים ?. ו-!.
תיצרו שני קבצים כדי לארגן את הקוד:
product.dart: הגדירו מחלקה בשםProductשמייצגת פריט במלאי. לחלק מהמוצרים יש מידע מלא, ואחרים עדיין נמצאים בתהליך רישום. המחלקה שלכם צריכה לכלול:String nameשאינו יכול להיות null — לכל מוצר חייב להיות שםdouble priceשאינו יכול להיות null — לכל מוצר חייב להיות מחירString? descriptionשיכול להיות null — לחלק מהמוצרים עדיין אין תיאורString? categoryשיכול להיות null — חלק מהמוצרים עדיין לא סווגו- בנאי שמקבל את
nameואתpriceכפרמטרים נדרשים - מתודה בשם
getDescriptionLength()שמחזירה את אורך התיאור באמצעות?., אוnullאם אין תיאור - מתודה בשם
getCategoryUppercase()שמחזירה את הקטגוריה באותיות גדולות באמצעות!— המתודה מניחה שהקטגוריה הוגדרה - מתודה בשם
displayProduct()שמדפיסה את פרטי המוצר, ומציגהNo descriptionכאשר התיאור הוא null ו-Uncategorizedכאשר הקטגוריה היא null
main.dart: ייבאו את מחלקת המוצר והדגימו את שני האופרטורים:- צרו מוצר בשם
'Laptop'במחיר999.99, ואז הגדירו את התיאור שלו כ-'High-performance computing device'ואת הקטגוריה שלו כ-'Electronics' - צרו מוצר בשם
'Mystery Item'במחיר49.99(השאירו את התיאור והקטגוריה בתור null) - עבור Laptop: קראו למתודה
displayProduct(), הדפיסוDescription length: [length]באמצעותgetDescriptionLength(), והדפיסוCategory: [uppercase]באמצעותgetCategoryUppercase() - עבור Mystery Item: קראו למתודה
displayProduct()והדפיסוDescription length: [length]באמצעותgetDescriptionLength()(הדבר יציגnull)
- צרו מוצר בשם
המתודה displayProduct() צריכה להדפיס בפורמט הזה:
Product: [name] - $[price]
Description: [description or "No description"]
Category: [category or "Uncategorized"]פלט צפוי:
Product: Laptop - $999.99
Description: High-performance computing device
Category: Electronics
Description length: 32
Category: ELECTRONICS
Product: Mystery Item - $49.99
Description: No description
Category: Uncategorized
Description length: nullנסו בעצמכם
import 'product.dart';
void main() {
// TODO: צרו מוצר בשם 'Laptop' במחיר 999.99
// לאחר מכן הגדירו את התיאור שלו ל-'High-performance computing device'
// והגדירו את הקטגוריה שלו ל-'Electronics'
// TODO: צרו מוצר בשם 'Mystery Item' במחיר 49.99
// השאירו את התיאור ואת הקטגוריה כ-null
// TODO: עבור Laptop:
// - קראו ל-displayProduct()
// - הדפיסו "Description length: [length]" באמצעות getDescriptionLength()
// - הדפיסו "Category: [uppercase]" באמצעות getCategoryUppercase()
// TODO: עבור Mystery Item:
// - קראו ל-displayProduct()
// - הדפיסו "Description length: [length]" באמצעות getDescriptionLength()
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים
קבצים חיצונייםספריות וייבואמבוא לתכנות מונחה עצמיםמחלקות לעומת אובייקטיםמילת המפתח thisמתודותמשתני מופעיסודות הבנאיחזרה: מחשבון פשוט4בטיחות מפני ערכי null
מבוא לבטיחות מפני ערכי nullניתן להקצאה ל-null לעומת לא ניתן להקצאה ל-nullהאופרטורים ? ו-!מילת המפתח Late ובטיחות מפני ערכי nullאופרטורים מודעי nullבטיחות מפני ערכי null במחלקותסיכום – מערכת פרופילי משתמשים7מחלקות מופשטות וממשקים
מחלקות מופשטותמתודות מופשטותממשקים ב-Dartממשקים משתמעיםמימוש לעומת הורשהממשקים מרוביםחזרה – מחשבון צורות10אוספים וגנריות
סקירה כללית של List, Set ו-Mapאוספים בטוחים מבחינת טיפוסיםמחלקות גנריותמתודות גנריותאילוצים גנרייםIterable ו-Iteratorסיכום – אחסון גנרי13מושגי OOP מתקדמים
הרכבה לעומת הורשהמתודות הרחבהמחלקות קריאותמחלקות אטומות (Dart 3)רשומות (Dart 3)תבניות והתאמה (3.0)טיפוסים מונים עם מתודות16פרויקט: ניהול ספרייה
סקירת הפרויקטמחלקות ספר ומשתמש2בנאים ב-Dart
בנאי ברירת מחדלבנאים בעלי שםרשימות אתחולבנאים קבועיםבנאי Factoryבנאים מפניםסיכום - בונה צורות5כימוס
חברים ציבוריים לעומת פרטייםמוסכמת הקידומת _פרטיות ברמת הספרייההעמקה ב-getters וב-settersהסתרת מידעסיכום – רשומות תלמידים8מיקסינים
מבוא למיקסיניםיצירת מיקסיניםשימוש במספר מיקסיניםמילת המפתח on במיקסיניםמיקסינים לעומת ירושהמיקסינים לעומת ממשקסיכום – מערכת בעלי החיים3מאפייני מחלקה
איברי מופע לעומת איברים סטטייםשדות final ו-constמשתני lateמתודות ושדות סטטייםGetters ו-Settersסיכום – מנהל חשבונות בנק6ירושה
ירושה בסיסיתמילת המפתח superדריסת מתודותהאנוטציה @overrideמילת המפתח final למחלקהבנאים וירושהסיכום – היררכיית עובדים9פולימורפיזם
יסודות הפולימורפיזםפולימורפיזם באמצעות ממשקיםבדיקת טיפוסים בזמן ריצההאופרטורים is ו-asמילת המפתח קווריאנטיסיכום — מעבד תשלומים12תכנות מונחה עצמים אסינכרוני
Future-ים ו-async/awaitיסודות ה-Streamsבקרי Streamsבנאים אסינכרונייםאסינכרוניות במתודות של מחלקהסיכום - אחזור נתוניםתרגלו בעצמכם: קומפיילר Dart אונליין