ראסט (שפת תכנות)

מתוך המכלול, האנציקלופדיה היהודית
קפיצה לניווט קפיצה לחיפוש
ראסט
Rust
גרסה אחרונה 1.58.1 (20 בינואר 2022[1])
השפיעה על Crystal, Elm, Idris, Spark, Swift, Project Verona, Zig, PHP
סיומת rs, rlib
www.rust-lang.org

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

שפת ראסט משלבת יכולת ביצועים גבוהים כמו של שפת C לצד רמת בטיחות גבוהה. חלק מן הבעיות האופפות את C (למשל גלישת חוצץ) לא אפשריות בראסט.

התחביר של השפה פשוט וקל ללמידה.

השפה זכתה בתואר "שפת התכנות האהובה ביותר" לשנים 2016 עד 2021 בסקר קהילת המתכנתים של StackOverflow[2].

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

ב-8 בפברואר 2021, הוקמה קרן ראסט (Rust Foundation) במטרה לפקח ולקדם את שפת התכנות[3].

דוגמאות

Hello World

דוגמה לתוכנית Hello world הכתובה בראסט. המאקרו println! מדפיס הודעה להתקן היציאה התקני (מסך).

fn main() {
    println!("Hello World!");
}

חישוב עצרת

רקורסיבי

fn factorial(i: u64) -> u64 {
	match i {
		0 => 1,
		n => n * factorial(n-1)
	}
}

איטרטיבי

fn factorial(i: u64) -> u64 {
	let mut acc = 1;
	for num in 2..=i {
		acc *= num;
	}
	acc
}

באמצעות איטרטור

fn factorial(i: u64) -> u64 {
	(1..=i).product()
}

מנגנון הטיפוסים

מנגנון טיפוסים סטטי - הכל נקבע בזמן הידור (ולמרות שאפשר להגדיר משתנים מקומיים בלי הצהרת הטיפוס זה רק כשברור בצורה דטרמיניסטית מהו הטיפוס - גם במקרה של שימוש במנגנון Options או Result, בשביל להשתמש בטיפוס כזה בקוד צריך לפתוח אותו על ידי match או unwrap, כך שהקוד תמיד דטרמיניסטי).

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

מנגנון טיפוסים חזק - אין המרה מרומזת בין טיפוסים.

דוגמאות לטיפוסיים עיקריים

Signed int - i8, i16, i32, i64, i128

Unsigned int - u8, u16, u32, u64, u128

Float - f32, f64

Boolean - bool

Character - char

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

Array - בניגוד ל-Tuple, יכול להכיל סוג טיפוס אחד. בעל אורך קבוע.

Vector  - דומה ל-Array אבל בעל אורך משתנה.

String  - אוסף של בתים שמהווים מחרוזת תקנית לפי תקן UTF-8[4].

HashMap  - מיפוי על ידי שימוש ב- key ו- value.

Struct  - מגדירים את שם ה- Struct, שמות השדות והסוג של השדות, ניתן לממש פונקציות.

Struct, trait ופולימורפיזם

בשפה אין ירושה אך יש מנגנונים אחרים המאפשרים תכנות מונחה עצמים.

Struct - מבנה המאפשר שמירת נתונים והגדרת פונקציות.

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

בשפה אין הורשה או ממשקים, ישנן שתי דרכים ליצור משהו שדומה לאלו:

1 – במקום ירושה פשוטה אפשר להשתמש ב-composition (במקרים שזה מתאים).

2 – אפשר לממש trait אחד עבור כמה struct. זה מאפשר פולימורפיזם כי אפשר להתייחס לאובייקט אחד על פי של-trait שהוא מממש. מימוש trait עבור struct נותן גם יכולת הדומה למימוש ממשק (ניתן להגדיר trait בלי מימוש וניתן לממש trait אחד עבור כמה סוגים).

Option & Result

Option & Result – טיפוס העשוי להכיל משתנה ממשי (some) או  None (או Ok ו- Err עבור Result), זה מאפשר להתייחס למקרה בו אין את המידע המבוקש (כמו Nullabe ב-#C) ולכן בדרך כלל משמש לבדיקת תקינות הערך המוחזר מפונקציה.

בנוסף בראסט ישנו מנגנון קפדני המונע שגיאות של גישה ל-None – המהדר יוודא שבכל קוד שמשתמש במשתנה מסוג option יהיה match או unwrap ובשתי האפשרויות חייב להיות טיפול למקרה של None.

שתי דרכים לשימוש בערך הפנימי של משתנה מוכמס:

Match - מספק תבנית התאמה שמשמשת אותו כמו switch ב-C. התבנית מחזירה ערך ו\או מבצעת קוד כתלות בפרמטר. משמש גם לבדיקה האם some וטיפול במקרה של None.

Unwrap – פונקציה זו מחלצת את המשתנה הפנימי מתוך Option & Result במקרה של some – כלומר שקיים ערך ממשי ולא None. הפונקציה מחזירה שגיאה במקרה של None, ועוצרת את ריצת התוכנית[5], ולכן עדיפה לשימוש רק כאשר אין סיבה להמשיך את ריצת התוכנית אם הערך לא קיים.

מנגנון ה-Ownership

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

הוא מונע טעויות של 'דליפה' של שאריות מידע שאינן בתוקף ומשימוש במידע שכבר היה בשימוש.

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

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

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

בטיחות

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

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

השפה מבטיחה בזמן הידור שלא יהיו גישות למצביע null ושלא ייווצרו מצביעים מתנדנדים (dangling).

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

הערות שוליים

  1. ^ Announcing Rust 1.58.1
  2. ^ Stack Overflow Developer Survey 2021, Stack Overflow, ‏2021-08-01
  3. ^ אשלי וויליאמס, Hello World!, אתר קרן ראסט, ‏2021-02-08
  4. ^ String in std::string - Rust, doc.rust-lang.org
  5. ^ Option & unwrap - Rust By Example, doc.rust-lang.org

קישורים חיצוניים

Logo hamichlol.png
הערך באדיבות ויקיפדיה העברית, קרדיט,
רשימת התורמים
רישיון cc-by-sa 3.0