مراجعة كود Rust: 5 ملاحظات سيقدمها كل مطور كبير

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا Rust صارم جدًا، وكيف تساعد مراجعة الكود في الحفاظ على الصحة العقلية

\n

لقد كتبت كودًا بلغة Rust. تم تجميعه - مرحى! ولكن المشكلة: المطور الكبير، عند فتح طلب السحب الخاص بك، يتنهد ويبدأ في كتابة التعليقات. هل هذا مألوف؟ Rust هي لغة ذات فلسفة فريدة: إنها تثق بك، ولكنها تتحقق من كل شيء. ومع ذلك، فإن المترجم لا يرى ما تراه العين الخبيرة. لن يقول: "مرحبًا، يمكن فعل هذا بشكل أكثر أناقة" أو "الكود الخاص بك يتسرب - ليس بالذاكرة، بل بالأداء".

\n

في هذه المقالة، سنجري مراجعة كود Rust ونحلل الملاحظات النموذجية للمطورين الكبار. ستتعلم كيفية تحويل "الكود الذي يعمل فقط" إلى كود اصطلاحي وموثوق. هيا بنا!

\n\n

1. تجاهل نظام الأنواع: "دعني أضع كل شيء في String"

\n

الخطأ الأكثر شيوعًا للمبتدئين هو استخدام String أو الأنواع العامة حيث تكون الأنواع المحددة مطلوبة. سيقول المطور الكبير: "يجب أن يعكس نوعك منطق الأعمال، وليس مجرد أن يكون سلسلة نصية".

\n

المشكلة: فقدان الدلالة

\n

تخيل أنك تكتب دالة للعمل مع عناوين البريد الإلكتروني:

\n
fn send_email(to: String, subject: String, body: String) {\n    // ...\n}
\n

ما الخطأ هنا؟ يمكنك الخلط بين to و subject - لن يلاحظ المترجم. سيقترح المطور الكبير استخدام نمط newtype:

\n
struct Email(String);\nstruct Subject(String);\nstruct Body(String);\n\nfn send_email(to: Email, subject: Subject, body: Body) {\n    // ...\n}
\n

هل يبدو هذا زائدًا عن الحاجة؟ في مراجعة كود Rust، هذا النهج هو المعيار الذهبي. إنه يجعل الكود موثقًا ذاتيًا ويستبعد فئة كاملة من الأخطاء.

\n\n

2. الإفراط في استخدام clone(): النسخ لا يعني الملكية

\n

غالبًا ما يستخدم المطورون المبتدئون .clone() في كل مكان حيث يشتكي المترجم من الاقتراض. سيقول المطور الكبير: "أنت تستسلم ببساطة أمام مدقق الاقتراض. فكر بطريقة مختلفة".

\n

مثال: clone غير ضروري

\n
fn process(data: Vec<i32>) {\n    let first = data[0].clone();\n    let second = data[1].clone();\n    // ...\n}
\n

i32 ينفذ trait Copy - clone() هنا غير ضروري تمامًا. لكن المشكلة أعمق: إذا كنت تستنسخ هياكل كبيرة (مثل Vec أو String)، فستحصل على ضربة في الأداء.

\n

النهج الصحيح هو العمل مع المراجع:

\n
fn process(data: &[i32]) {\n    let first = &data[0];\n    let second = &data[1];\n    // ...\n}
\n

في مراجعة كود Rust، يجب عليك شرح سبب استنساخك. إذا كانت الإجابة "حتى لا يشتكي المترجم" - فاستعد لتعليق مدمر.

\n\n

3. معالجة الأخطاء السيئة: .unwrap() ليس حلاً نهائيًا

\n

يكره المطورون الكبار unwrap() و expect() في كود الإنتاج. لماذا؟ لأنهما يحولان الخطأ القابل للاسترداد إلى حالة ذعر. والذعر في Rust يعني إنهاء الطوارئ.

\n

ما الخطأ في هذا الكود؟

\n
let file_content = std::fs::read_to_string("config.txt").unwrap();
\n

إذا لم يكن الملف موجودًا - سينهار البرنامج. سيقترح المطور الكبير:

\n
let file_content = std::fs::read_to_string("config.txt")\n    .map_err(|e| format!("Failed to read config: {}", e))?;
\n

استخدم عامل ? وأنواع الأخطاء الخاصة بك. هذا هو أساس Rust الاصطلاحي. في مراجعة كود Rust، هذه واحدة من أولى الملاحظات.

\n\n

4. الأداء المنسي: التخصيصات والمكررات

\n

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

\n

مثال: التجميع بدون حاجة

\n
let numbers: Vec<i32> = (0..100).collect();\nlet doubled: Vec<i32> = numbers.iter().map(|x| x * 2).collect();                

المدونات

توصيات الكتب