פולימורפיזם ב Rust




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

Rust שונה מאוד מהשפות העיקריות שעבדתי איתן לפני (python ו c#) בהרבה מובנים כמו ניהול הזיכרון, העובדה שאין קלאסים והורשה, ניהול השגיאות, והקומפיילר שעובד שונה לחלוטין.

הפוסט הזה ידבר על Polymorphism, אחת התכונות הבסיסיות, העיקריות והחשובות של תכנות מונחה עצמים. ההבנה של הקונספט היא בעיני הכרחית לכל מפתח על מנת לכתוב קוד מודלרי יותר, פשוט יותר לקריאה, וקל יותר להרחבה. יצא לי לדבר לא פעם על Polymorphism בבלוג וכמובן, בכל פעם שהצגתי אותו (ב c# או python) זה היה באמצעות הגדרת מחלקות וביצוע הורשה בניהן.

איך מתבצע פולימורפיזם בראסט?

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

באמצעות שימוש ב traits אנחנו יכולים להגדיר סט חתימות של פונקציות ש type יכול לממש (קצת דומה ל interface).

כאשר יש לנו מספר structs שכולם מממשים את אותו ה trait אנחנו יכולים להתייחס אליהם באופן זהה כשאנחנו משתמשים בפונקציונאליות שלהם.

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


באמצעות ה trait keyword הגדרנו את החוזה שעל ה structs לממש ובאמצעות impl x for y אנחנו מגדירים ש y הוא type שמימש את החוזים של x.

כעת אפשר להשתמש בשני ה structs שהגדרנו באמצעות גישה לממשק שהוגדר ב trait printable


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

let items: Vec<&dyn Printable> = vec![&book, &magazine]; 

כאן בעצם הגדרנו vector בשם items מסוג Printable שהאיברים שלו הם book ו magazine.

הדבר היחידי שקצת שונה או חריג כאן זה הוא השימוש ב dyn. השימוש במילה השמורה dyn מגדיר לקומפיילר שאנחנו לא יודעים איזה type אנחנו נפגוש בזמן הקומפילציה ולכן יצטרך לחכות לזמן הריצה בשביל קבלת ההחלטה. הקונספט נקרא "dynamic dispatch" וקיים במגוון שפות. חשוב לציין שלdynamic dispatch קיימים חסרונות מבחינת עלויות בזמן ריצה בשל קבלת החלטות נוספת שצריכה להעשות ויש לקחת את זה בחשבון. (אפשר להתעמק כאן)

תגובות

פוסטים פופולריים מהבלוג הזה

תכנות מונחה עצמים | Dependency Inversion Principle

מהם קבצי DLL ואיך להשתמש בהם?

מה ההבדל בין אוטומציה לפיתוח רגיל