דלג לתוכן הראשי

מבנים

סקירה כללית

מבני השפה Wave הם אלמנט תחבירי מרכזי להצהרה על טיפוסי נתונים מותאמים אישית. מבנה מאפשר חיבור ערכים מסוגים שונים ליחידה לוגית אחת, ובכך מאפשר דגם מורכב של מבנים בצורה ברורה ובטוחה.

מבני Wave פועלים כטיפוסי ערכים. כל שדה חייב להכיל טיפוס מוגדר, ובזמן יצירת מופע כל השדות חייבים להיות מאותחלים. חוקים אלו מבטיחים שמצב המבנה תמיד יהיה מושלם וניתן לחיזוי.

תחביר הצהרת מבנים

מבנה מוכרז בעזרת מילת המפתח struct. שמות מבנים כתובים בתבנית פסקל (PascalCase) ומבנה יכול להכיל שדה אחד או יותר.

השדות מוכרזים בפורמט שם: סוג;, ויש צורך בנקודה פסיק אחרי כל הכרזה של שדה.

struct Box {
size: i32;
weight: f32;
}

סדר השדות שנכתבים בהצהרת מבנה זהה לסדר האחסון בזיכרון. בתוך מבנה ניתן לכלול רק הצהרות על שדות, ולא ניתן לכלול פונקציות או שיטות. לוגיקת הפעולה מוגדרת מחוץ למבנה בצורה נפרדת.

תחביר יצירת מבנים

מבנה נוצר באופן ליטרלי על ידי שימוש בשם המבנה. ליטרל של מבנה נכתב בצורה StructName { שם שדה: ערך; ... נכתב בצורה }.

var b: Box = Box {
size: 42;
weight: 10.5;
};

בעת יצירת מבנה כל השדות שהוגדרו חייבים להיות מאותחלים ובמקרה של השמטה, תתרחש שגיאת קומפילציה.

בעת האתחול, סדר כתיבת השדות אינו חייב להתאים לסדר הכרזת המבנה, אך סוג הערך המועבר לכל שדה חייב להתאים במדויק לסוג שהוגדר במבנה. ב-Wave לא מתאפשרת המרה עלומה של סוגים בתהליך אתחול שדות מבנה.


תחביר גישה לשדות במבנה

גישה לשדות במבנה מתבצעת בעזרת תחביר נקודה. גישה לשדה היא חלקה, גם בקריאה וגם בכתיבה.

println("גודל: {}", b.size);
println("משקל: {}", b.weight);

שימוש בשם של שדה שאינו קיים גורם לשגיאת קומפילציה. העברת מבנה בתור ערך משמעותה שכל השדות מועתקים בעת ההעברה.


תחביר הגדרת פעולות למבנים

Wave אינה מאפשרת להגדיר פונקציות ישירות בתוך מבנה. במקום זאת, משתמשים במילת proto כדי להצהיר פעולות הקשורות למבנה.

בלוק proto הוא מרחב של פונקציות הקשורות למבנה מסוים, והפונקציות המוגדרות בתוך בלוק זה משמשות כשיטות לאותו מבנה.

שיטה מקבלת את מופע המבנה כפרמטר ראשון באמצעות self. self מייצג את ערך המבנה כולו, ומועבר בשיטת העתקת ערך.

proto Box {
fun print(self) {
println("size={}, weight={}", self.size, self.weight);
}

fun added_size(self, x: i32) -> i32 {
return self.size + x;
}
}

בלוק proto אינו חייב להיות באותו קובץ עם הכרזת המבנה, וניתן להגדיר מנגנוני proto מרובים לאותו מבנה.

קריאת שיטה נעשית באמצעות תחביר נקודה ומתבצע באותו אופן כמו קריאת פונקציה רגילה.

b.print();
var n: i32 = b.added_size(5);

שימוש במבנה כפרמטר של פונקציה

העברת מבנה כפרמטר לפונקציה מתבצעת בשיטת העתקת ערך. גם אם משנים את השדות של המבנה בתוך הפונקציה, זה לא משפיע על המופע המקורי מאיפה שנקראה הפונקציה.

fun calc(box: Box) -> i32 {
return box.size * 2;
}

גם כאשר משתמשים במבנה כערך מוחזר מפונקציה, מתבצעת העתקת ערך. התנהלות זו מבטיחה את שמירת המבנה וזרימת נתונים צפויה.


מבנה מקונן (Nested Struct)

ב-Wave ניתן להשתמש במבנה אחר כסוג שדה של מבנה. כיוון שהמבנה הוא סוג שלם, ניתן לקנן מבנים בתוך מבנים בצורה חופשית.

struct Position {
x: i32;
y: i32;
}

struct Player {
name: str;
pos: Position;
}

לגישה לשדות של מבנה מקונן משתמשים בנקודה בתחביר עוקב.

var p: Player = Player {
name: "Alice";
pos: Position { x: 10; y: 20; };
};

println("נגן X: {}", p.pos.x);
println("נגן Y: {}", p.pos.y);

ניתן לקנן מבנה קבוצתי בתוך מבנה קבוצתי אחר, וכללי אתחול השדות חלים גם כאן.


מערך של מבנים

ניתן להשתמש במבנה כסוג של אלמנט במערך. תחביר המערכים של Wave משתמש בפורמט array<סוג, אורך>, וגם סוג מבנה ניתן להגדיר.

var players: array<Player, 3> = [
Player { name: "A"; pos: Position { x: 1; y: 2; }; },
Player { name: "B"; pos: Position { x: 3; y: 4; }; },
Player { name: "C"; pos: Position { x: 5; y: 6; }; }
];

כדי לגשת לאלמנט במערך מבנים, משתמשים קודם באינדקס של המערך ואז בנקודה כדי לגשת לשדות המבנה הפנימיים.

println("שחקן שני X: {}", players[1].pos.x);

יכולת הביצוע של פעולות בסיסיות על המבנה

מבנה ב-Wave הוא סוג מוגדר משתמש ולכן אינו משתתף אוטומטית בפעולות אריתמטיות או בהשוואת ערכים.

אם יש צורך בהשוואה לשוויון, מיון, האשינג, או פעולות מספריות עם מבנה, יש להגדיר פעולה זו במפורש דרך בלוק proto. Wave אינה מספקת אופרטורים סמויים עבור מבנים, כל פעולה צריכה להיות מוגדרת במפורש.