المؤشرات الذكية (Smart Pointers)
المؤشر (Pointer) هو مفهوم عام لمتغير يحتوي على عنوان في الذاكرة. يشير هذا العنوان إلى بيانات أخرى أو “يؤشر عليها”. النوع الأكثر شيوعاً للمؤشرات في لغة Rust هو المرجع (Reference)، والذي تعرفت عليه في الفصل الرابع. يُشار إلى References بالرمز & وهي تستعير (Borrow) القيمة التي تشير إليها. لا تمتلك References أي قدرات خاصة سوى الإشارة إلى البيانات، وليس لها أي أعباء إضافية (Overhead).
أما المؤشرات الذكية (Smart Pointers)، فهي من ناحية أخرى هياكل بيانات (Data Structures) تعمل مثل Pointer ولكنها تمتلك أيضاً بيانات وصفية (Metadata) وقدرات إضافية. مفهوم Smart Pointers ليس فريداً في Rust: فقد نشأت Smart Pointers في لغة ++C وهي موجودة في لغات أخرى أيضاً. تمتلك Rust مجموعة متنوعة من Smart Pointers المعرفة في المكتبة القياسية (Standard Library) والتي توفر وظائف تتجاوز تلك التي توفرها References. لاستكشاف المفهوم العام، سنلقي نظرة على زوجين من الأمثلة المختلفة لـ Smart Pointers، بما في ذلك نوع المؤشر الذكي بعدّ المراجع (Reference Counting). يتيح لك هذا Pointer السماح للبيانات بامتلاك مالكين متعددين من خلال تتبع عدد المالكين، وعندما لا يتبقى أي مالك، يتم تنظيف البيانات.
في Rust، ومع مفهوم الملكية (Ownership) والاستعارة (Borrowing) الخاص بها، هناك فرق إضافي بين References و Smart Pointers: فبينما تستعير References البيانات فقط، فإن Smart Pointers في كثير من الحالات تملك (Own) البيانات التي تشير إليها.
عادةً ما يتم تنفيذ Smart Pointers باستخدام الهياكل (Structs). وعلى عكس Struct العادي، تنفذ Smart Pointers سمات (Traits) Deref و Drop. تسمح Trait Deref لمثيل (Instance) من هيكل Smart Pointer بالتصرف مثل Reference بحيث يمكنك كتابة الشفرة البرمجية (Code) الخاصة بك لتعمل مع كل من References أو Smart Pointers. وتسمح لك Trait Drop بتخصيص Code الذي يتم تشغيله عندما يخرج Instance من Smart Pointer عن النطاق (Scope). في هذا الفصل، سنناقش كلتا السمتين ونوضح سبب أهميتهما لـ Smart Pointers.
بما أن نمط المؤشر الذكي (Smart Pointer Pattern) هو نمط تصميم عام يُستخدم بشكل متكرر في Rust، فإن هذا الفصل لن يغطي كل Smart Pointer موجود. تمتلك العديد من المكتبات (Libraries) مؤشرات ذكية خاصة بها، ويمكنك حتى كتابة المؤشرات الخاصة بك. سنغطي Smart Pointers الأكثر شيوعاً في Standard Library:
Box<T>، لتخصيص القيم في الذاكرة الكومة (Heap)Rc<T>، وهو نوع Reference Counting يتيح الملكية المتعددةRef<T>وRefMut<T>، اللذان يتم الوصول إليهما من خلالRefCell<T>، وهو نوع يفرض قواعد Borrowing في وقت التشغيل (Runtime) بدلاً من وقت الترجمة (Compile Time)
بالإضافة إلى ذلك، سنغطي نمط القابلية للتعديل الداخلية (Interior Mutability) حيث يكشف نوع غير قابل للتعديل (Immutable Type) عن واجهة برمجة تطبيقات (API) لتعديل قيمة داخلية. سنناقش أيضاً دورات المراجع (Reference Cycles): كيف يمكن أن تسرب الذاكرة (Memory Leak) وكيفية منع ذلك.
فلنبدأ!