يستخدم Rust مدقق استعارة لفرض قواعد الملكية الخاصة به والتأكد من أن البرامج آمنة للذاكرة. تحدد قواعد الملكية كيفية إدارة Rust للذاكرة عبر المكدس والكومة.

أثناء كتابة برامج Rust، ستحتاج إلى استخدام المتغيرات دون تغيير ملكية القيمة المرتبطة. يوفر Rust آلية استعارة قوية لتشجيع المرونة وإعادة استخدام الكود.

ما هو الاقتراض في الصدأ؟

الاقتراض هو الوصول إلى قيمة المتغير دون الحصول على ملكية المتغير عن طريق الرجوع إلى المالك. يضمن مدقق الاستعارة أن المرجع صالح، ولا يتم إسقاط البيانات باستخدام بنية تسمى lifetimes.

العمر هو مدة وجود المتغير. تبدأ مدة الحياة عند الخلق المتغير وتنتهي عند التدمير المتغير. يمكنك استعارة ملكية متغير، وعندما يكون المرجع المقترض خارج النطاق، تعود الملكية إلى متغير المالك. يشبه الاقتراض المؤشرات التي ستجدها في لغات مثل C ++ و Go. لكن مترجم Rust يستخدم مدقق الاستعارة للتأكد من أن البرامج آمنة للذاكرة.

مثال على الاقتراض في الصدأ

يمكنك استعارة ملكية المتغير عن طريق الرجوع إلى المالك باستخدام رمز العطف (&).

 fn main {
let x = String ::from("hello");
let y = &x;
println! ("{}", x);
println! ("{}", y)
}

fn main {
let x = String ::from("hello");
let y = &x;
println! ("{}", x);
println! ("{}", y)
}

fn main {
let x = String ::from("hello");
let y = &x;
println! ("{}", x);
println! ("{}", y)
}

fn main {
let x = String ::from("hello");
let y = &x;
println! ("{}", x);
println! ("{}", y)
}

fn main {
let x = String ::from("hello");
let y = &x;
println! ("{}", x);
println! ("{}", y)
}

fn main {
let x = String ::from("hello");
let y = &x;
println! ("{}", x);
println! ("{}", y)
}

بدون الاقتراض من خلال الإحالة، سيصاب البرنامج بالذعر. قد ينتهك قاعدة الملكية أن القيمة يمكن أن يكون لها مالك واحد، ومتغيرين لا يمكن أن يشيران إلى نفس موقع الذاكرة. يمكن أن يكون الاقتراض مفيدًا جدًا في الوظائف. فيما يلي مثال على استعارة دالة، للاحتفاظ بالملكية أثناء استدعاء الدوال الأخرى التي تأخذ المتغيرات المحلية كوسيطات.

 fn print_even (vectr: & Vec < i32 >) {
for values in vectr {
if values % 2 == 0 {
println! ("{}", values);
}
}
}

fn print_even (vectr: & Vec < i32 >) {
for values in vectr {
if values % 2 == 0 {
println! ("{}", values);
}
}
}

fn print_even (vectr: & Vec < i32 >) {
for values in vectr {
if values % 2 == 0 {
println! ("{}", values);
}
}
}

fn print_even (vectr: & Vec < i32 >) {
for values in vectr {
if values % 2 == 0 {
println! ("{}", values);
}
}
}

fn print_even (vectr: & Vec < i32 >) {
for values in vectr {
if values % 2 == 0 {
println! ("{}", values);
}
}
}

fn print_even (vectr: & Vec < i32 >) {
for values in vectr {
if values % 2 == 0 {
println! ("{}", values);
}
}
}

fn print_even (vectr: & Vec < i32 >) {
for values in vectr {
if values % 2 == 0 {
println! ("{}", values);
}
}
}

تشير الدالة print_even إلى متجه من الأعداد الصحيحة 32 بت كوسيطة. ثم يقوم بطباعة سطور من القيم التي تكون مضاعفات الرقمين في المتجه باستخدام حلقة for-loop و println! ماكرو.

 fn main {
let number_vector = vec! [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ];
print_even(&number_vector);
println! ("The main function retains ownership of the number vector{:?}", number_vector)
}

fn main {
let number_vector = vec! [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ];
print_even(&number_vector);
println! ("The main function retains ownership of the number vector{:?}", number_vector)
}

fn main {
let number_vector = vec! [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ];
print_even(&number_vector);
println! ("The main function retains ownership of the number vector{:?}", number_vector)
}

fn main {
let number_vector = vec! [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ];
print_even(&number_vector);
println! ("The main function retains ownership of the number vector{:?}", number_vector)
}

fn main {
let number_vector = vec! [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ];
print_even(&number_vector);
println! ("The main function retains ownership of the number vector{:?}", number_vector)
}

تقوم الوظيفة الرئيسية بتعريف المتغير number_vector وتخصيص متجه من الأعداد الصحيحة ذات 32 بت. ثم تستدعي الدالة print_even وتمررها كمرجع إلى المتغير number_vector باستخدام رمز العطف.

تحتفظ الوظيفة الرئيسية بملكية متغير number_vector حيث يمكنها الاستمرار في استخدام القيمة في موقع الذاكرة الخاص بها.

نتيجة الاقتراض بالرجوع إلى Rust

الاقتراض والتحول المراجع

يمكن للوظائف أيضًا تعديل المتغيرات المستعارة باستخدام مراجع قابلة للتغيير إليها، قبل إعادة الملكية.

ومع ذلك، على عكس المتغيرات العادية التي يمكن تعيينها على متغير باستخدام الكلمة الأساسية mut، يجب أن تسبق المراجع القابلة للتغيير برمز علامة العطف.

قبل عمل مراجع قابلة للتغيير، يجب أن يكون المتغير الذي ترغب في تعديله قابلاً للتغيير.

 fn remove_value (vectr: & mut Vec < i32 >) -> & Vec < i32 > {
vectr.remove( 4 );
return vectr
}

fn rem ove_value (vectr: & mut Vec < i32 >) -> & Vec < i32 > {
vectr.remove( 4 );
return vectr
}

fn remove_value (vectr: & mut Vec < i32 >) -> & Vec < i32 > {
vectr.remove( 4 );
return vectr
}

fn remove_value (vectr: & mut Vec < i32 >) -> & Vec < i32 > {
vectr.remove( 4 );
return vectr
}

تأخذ وظيفة remove_value مرجع متجه قابل للتغيير لأعداد صحيحة 32 بت. تقوم بإرجاع متجه من الأعداد الصحيحة 32 بت بعد إزالة قيمة المتجه في الفهرس الرابع.

 fn main {
let mut nums = vec! [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ];
remove_value(& mut nums);
println! ("{:?}", nums);
}

fn main {
let mut nums = vec! [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ];
remove_value(& mut nums);
println! ("{:?}", nums);
}

fn main {
let mut nums = vec! [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ];
remove_value(& mut nums);
println! ("{:?}", nums);
}

fn main {
let mut nums = vec! [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ];
remove_value(& mut nums);
println! ("{:?}", nums);
}

fn main {
let mut nums = vec! [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ];
remove_value(& mut nums);
println! ("{:?}", nums);
}

تقوم الوظيفة بتعديل متجه الأعداد عن طريق استدعاء remove_value وتمرير المرجع القابل للتغيير للمتجه كوسيطة. عند طباعة المتجه، لا يوجد الفهرس الرابع السابق للمتجه.

لاحظ أن الحجة هي إشارة إلى متجه قابل للتغيير.

نتيجة الاقتراض وتغيير المراجع في الصدأ

من المهم فهم الملكية والاقتراض

ستحتاج إلى فهم الملكية والاقتراض لكتابة كود Rust فعال وآمن للذاكرة يقوم بالتجميع والتشغيل. إذا كانت التعليمات البرمجية الخاصة بك لا تتبع قواعد الملكية، فسيقوم مدقق الاستعارة باكتشافها. ستحتاج إلى جعل برنامجك آمنًا للذاكرة حتى يتمكن Rust من تجميعه.

مدقق الاقتراض مزعج عندما تكون جديدًا في Rust. ولكن، عندما تكتب المزيد من كود Rust، ستعتاد عليه وتكتسب خبرة في كتابة كود Rust الآمن للذاكرة.