تختلف لغات البرمجة في كيفية تعاملها مع الذاكرة وفرض قواعد إدارة الذاكرة. توظف Go و Python جامعي القمامة ، بحيث يمكن للمطورين التركيز على كتابة التعليمات البرمجية. تمنح C و C ++ المبرمجين مسؤولية إدارة الذاكرة بمستوى أدنى.
يتعامل Rust مع إدارة الذاكرة بشكل مختلف ، باستخدام مفاهيم يطلق عليها اسم الملكية والاقتراض. يستخدم "فاحص الاستعارة" لفرض سلامة الذاكرة بكفاءة.
ما هي الملكية؟
الملكية هي ميزة واتفاقية من Rust تساعد على ضمان سلامة الذاكرة للبرامج بدون جامع القمامة. إنها طريقة أخرى للتدخل مشكلة تسرب الذاكرة في التعليمات البرمجية الخاصة بك.
يتحقق مترجم Rust مما إذا كان البرنامج يطيع قواعد الملكية في وقت الترجمة. إذا كان البرنامج يتبع هذه القواعد ، يمكن تشغيله. إذا لم يحدث ذلك ، فإن المترجم يرفض إنتاج ملف تنفيذي.
يتحقق Rust من قواعد الملكية باستخدام استعارة المدقق. يتحقق مدقق الاستعارة من نموذج الملكية ويقرر ما إذا كانت القيمة في الذاكرة (كومة أو كومة) خارج النطاق أم لا. إذا كانت القيمة خارج نطاقها ، فلا يمكن الوصول إليها من قبل أجزاء أخرى من البرنامج ما لم يتم استعارتها.
قواعد الملكية
في Rust ، يمتلك كل متغير القيمة التي تمت تهيئتها بها ، ولا يمكن أن يكون هناك سوى مالك واحد. بمجرد خروج المالك عن النطاق ، يتم إسقاط القيمة. من المهم فهم تفاصيل قواعد الملكية.
قاعدة الملكية الأولى هي أن كل متغير يمتلك قيمته المبدئية.
يترك مالك = سلسلة::من واحد")؛
ال صاحبة المتغير أعلاه يمتلك السلسلة واحد وعلى عكس لغات مثل Python و Go ، سيتم إسقاط هذه القيمة عند إعادة التعيين المتغيرة.
قاعدة الملكية الثانية هي أن متغيرين لا يمكن أن يشيران إلى نفس موقع الذاكرة ؛ يمكن أن يكون لكل قيمة مالك واحد فقط.
يترك new_owner = مالك ؛
ال مالك جديد المتغير الآن يمتلك القيمة المخزنة في موقع ذاكرة الملف صاحبة عامل. إذا حاولت استخدام ملف صاحبة متغيرًا ، سيصاب المترجم بالذعر ، وسيرفض إنشاء ملف تنفيذي.
في معظم اللغات التي تستخدم جامعي البيانات المهملة ، يمكن لمتغيرين أن يشيران إلى نفس موقع الذاكرة. في ما يلي مثال على شفرة جافا سكريبت المكافئة:
يترك المالك = "المالك" ؛
يترك new_owner = مالك ؛
وحدة التحكم.log (new_owner) ؛
يعمل تشغيل كود JavaScript أعلاه بدون أخطاء ، وإذا فعلت الشيء نفسه في Go أو Python ، فسيعمل برنامجك بدون أخطاء أيضًا.
قاعدة الملكية الثالثة هي أنه بمجرد خروج المتغير من النطاق المعلن ، يتم إسقاط القيمة ، ويتم إلغاء تخصيص الذاكرة.
// متغير في نطاق منفصل
{
يترك مثال = سلسلة:: من ("هذا نطاق جديد") ؛
}
مطبعة!("{}"، مثال)
لا يمكنك الوصول إلى مثال متغير خارج نطاقه ؛ محاولة القيام بذلك ستسبب ذعر المترجم.
الملكية في الوظائف
عندما تمرر قيمة إلى دالة كوسيطة ، يمكن للدالة الوصول إلى هذا المتغير على الرغم من عدم التصريح عنه في نطاقه:
الجبهة الوطنيةطابعة(القيمة: سلسلة) -> سلسلة {
إرجاع القيمة
}الجبهة الوطنيةرئيسي() {
يترك س = سلسلة:: from ("طباعة قيمة") ؛ // x يمتلك قيمة السلسلة
// تم نقل الملكية إلى وظيفة الطابعة هنا
مطبعة!("{} ال نتيجة من طباعة X هو أنه -: "، طابعة (x)) ؛
}
يمكن للوظيفة الوصول إلى هذا المتغير لأن Rust ينقل ملكيتها إلى الوظيفة في وقت الترجمة.
قد تعتقد أنه لا يزال من الممكن استخدام المتغير لاحقًا في نطاقه الأصلي:
الجبهة الوطنيةطابعة(القيمة: سلسلة) -> سلسلة {
إرجاع القيمة
}الجبهة الوطنيةرئيسي() {
يترك س = سلسلة:: from ("طباعة قيمة") ؛
مطبعة!("{} ال نتيجة من طباعة x هو أنه -: "، طابعة (x)) ؛
// محاولة استخدام المتغير بعد نقل ملكية قيمته
println!("{} لا ينبغي الوصول إليها" ، س)
}
ولكن إذا جربت هذا ، فسيصاب المترجم بالذعر ويرفض إنتاج ملف تنفيذي:
يعطي الصدأ الأولوية لإعادة استخدام الكود
تعد إمكانية إعادة استخدام الكود ممارسة أساسية ، ولكن لممارسة قابلية إعادة استخدام الكود ، يلزمك فهم قواعد ملكية Rust.
Rust هي لغة برمجة مرنة للغاية. يوفر مفاهيم مثل الاقتراض والنقل والنسخ والاستنساخ للملكية لإعادة الاستخدام المتغير.