היסודות
while מריצה את הגוף שלה כל עוד תנאי מטיפוס bool נשאר true:
while condition {
// גוף
}
הקומפיילר מחשב את התנאי לפני כל חזרה:
true: מריצים את הגוף ואז בודקים שוב.false: יוצאים מהלולאה.
המחשה פשוטה מתוך הדוגמאות של Zero, עם תנאי שכבר false:
הריצו את זה ורק ה-write השני יופעל. הגוף של ה-while אף פעם לא רץ, כי התנאי היה false בפעם הראשונה שנבדק.
התנאי הוא bool
כמו ב-if/else, תנאי הלולאה חייב להיות bool. Zero לא ממירה מספרים שלמים, מחרוזות או ערכים אחרים לבוליאני.
while count { // שגיאת קומפילציה
// ...
}
while count > 0 { // OK
// ...
}
התנאי יכול להיות כל דבר שמחושב ל-bool: קישור, השוואה, צירוף של &&/|| או קריאה לפונקציה. אותם כללים של if חלים גם כאן.
לולאות עם מונה
הדפוס הקלאסי של "לעשות משהו N פעמים" משתמש במונה וב-while:
let mut i = 0
while i < 10 {
// עבודה
i = i + 1
}
שלושה חלקים: ערך התחלתי, תנאי שמשווה מול הגבול, ועדכון בתוך הגוף. זה הדפוס שיש בכל שפה אימפרטיבית: Zero פשוט לא עוטפת אותו במילת מפתח for.
הערה על הכתיב mut שלמעלה: הדרך שבה Zero כותבת קישורים ניתנים לשינוי בערכת הכלים שלכם עשויה להיות שונה בגרסאות שלפני 1.0. הריצו zero check --json על בדיקה קטנה כדי לוודא את התחביר המדויק שהקומפיילר שלכם מקבל. הדפוס הרעיוני (מונה, תנאי, עדכון) הוא החלק היציב.
לולאות אינסופיות
while שהתנאי שלה תמיד true רצה לנצח:
while true {
// ממתינים לעבודה, מטפלים בה, חוזרים שוב
}
זו הצורה הנכונה ללולאת אירועים, ל-REPL או לשרת שרץ לאורך זמן. כדי לצאת, מסיימים את התהליך, מעלים שגיאה מתוך הגוף, או בונים מחדש את הקוד כך שהתנאי יישבר.
מתי להשתמש בלולאה
לולאות הן כלי שכדאי להשתמש בו במשורה. דברים שנראים כמו לולאות בשפות אחרות מקבלים לעיתים קרובות צורה נקייה יותר ב-Zero:
- מעבר על אוסף קבוע: העדיפו פונקציה שהספרייה הסטנדרטית או ה-shape שלכם חושפים: פונקציית עזר בסגנון
forEach, פונקציית קיפול או מעבר רקורסיבי. - קריאה עד סוף הקלט: הריצו לולאה על קריאה שעלולה להיכשל, אבל השתמשו ב-
checkוב-raisesכדי לטפל בגבול בצורה נקייה במקום לקנן דגלי סטטוס. - המתנה לתנאי (polling): שקלו אם העיצוב צריך לתת לכם אות במקום זאת. לולאות polling הן סימן אזהרה בכל שפת מערכות.
אותו אינסטינקט חל על סוכנים: צורה הדוקה והצהרתית קלה יותר להבנה מלולאת מונה שנכתבה ידנית, גם לבני אדם וגם למחוללי קוד.
לולאות ואפקטים
גוף של while, כמו כל בלוק אחר, יכול לבצע קלט/פלט, אבל רק אם יש לו גישה ליכולת World (או לחלק ממנה). פונקציה שהחתימה שלה לא מזכירה את World יכולה להריץ לולאות כמה שתרצה, אבל לא יכולה לכתוב שום דבר החוצה. התכונה הזו נשמרת גם בתוך גוף הלולאה; הלולאה לא מעניקה יכולות חדשות.
זה נשמע מובן מאליו, אבל זו הסיבה שאפשר לשים while בתוך פונקציית חישוב "טהורה" ועדיין לדעת, מהחתימה בלבד, שהיא לא יכולה להדפיס שום דבר או לכתוב לדיסק.
הערות סגנון
כמה הרגלים קטנים שמשתלמים:
- שמרו על תנאי ברור. אם התנאי עושה עבודה של ממש, העבירו אותו לפונקציה או לקישור בעלי שם, כדי שהלולאה תיקרא בצורה נקייה.
- עדכנו את המונה בתחתית הגוף, לא במקומות מפוזרים בתוכו. כך קל יותר לזהות באגים של off-by-one.
- העדיפו תנאי יציאה מוקדמת שאפשר לבטא כתנאי של הלולאה עצמה על פני דגלים שמתהפכים באמצע חזרה. פחות חלקים נעים.
הבא בתור: Shapes
ראיתם עכשיו את זרימת הבקרה המרכזית של Zero. הפרק הבא עוסק במידול נתונים, ומתחיל ב-shapes, טיפוסי המכפלה של Zero בסגנון struct.
שאלות נפוצות
איך לולאות while עובדות ב-Zero?
משתמשים ב-while condition { ... }. התנאי מחושב לפני כל חזרה; אם הוא true, הגוף רץ והלולאה בודקת שוב. אם הוא false, הלולאה יוצאת והביצוע ממשיך אחרי הסוגר המסולסל. התנאי חייב להיות bool.
האם יש ב-Zero לולאת for?
Zero המוקדמת מגיעה עם while כמבנה הלולאה היחיד שלה. השפה שומרת בכוונה על משטח קטן בזמן שהיא מתייצבת: פחות מילות מפתח פירושן פחות דרכים שבהן סוכן יבחר את הצורה הלא נכונה. for על טווח או על אוסף עשוי להגיע בהמשך; עד אז, בונים את אותו דפוס עם while ומונה.
איך כותבים לולאה עם מונה ב-Zero?
מאתחלים מונה, מריצים while מולו ומעדכנים אותו בתוך הגוף: let mut i = 0; while i < 10 { ...; i = i + 1 }. תחביר השינוי של ערכים עדיין מתפתח ב-Zero שלפני 1.0, לכן בדקו בתיעוד העדכני את הכתיב המדויק. עם זאת, הדפוס של while + counter + update הוא הצורה המקובלת ללולאה עם מונה.
האם יש ב-Zero break או continue?
רוב השפות במשפחה של Zero מגיעות עם מבנה כלשהו ליציאה מוקדמת מלולאות; הכתיב המדויק ב-Zero שלפני 1.0 הוא אחד התחומים שעשויים להשתנות לפני 1.0. הגישה השמרנית היא לבנות את הלולאה כך שהתנאי עצמו יעשה את העבודה, להפוך ולעדכן את התנאי כך שהלולאה תצא באופן טבעי, במקום להסתמך על מילת מפתח ספציפית לזרימת בקרה.
האם לולאת while ב-Zero יכולה לרוץ לנצח?
כן. while true { ... } היא לולאה אינסופית. היא שימושית לשרתים, ללולאות אירועים, ל-REPL ולכל מקרה שבו אין תנאי סיום טבעי. בניגוד ל-truthiness מרומזת, true כאן הוא ליטרל מטיפוס bool, כך שהתנאי עדיין תקין מבחינת טיפוסים.