Clean Code في Rust: المبادئ والأمثلة العملية

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

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

ابدأ الدورة

مقدمة: لماذا يعتبر Clean Code مهمًا في Rust

\n

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

\n

سنركز على أربعة جوانب: الأسماء ذات المعنى، التعامل مع الأنواع والـ Traits، معالجة الأخطاء، وإعادة الهيكلة. سيتم توضيح كل مبدأ بكود يمكنك تطبيقه فورًا في مشاريعك.

\n\n

المبدأ 1: الأسماء ذات المعنى والهيكلة

\n

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

\n\n

أسماء المتغيرات والدوال

\n

تجنب الأسماء المكونة من حرف واحد (باستثناء الفهارس في الحلقات القصيرة). استخدم الأفعال للدوال والأسماء للمتغيرات.

\n
// سيء
fn c(a: &[i32]) -> i32 {
    a.iter().sum()
}

// جيد
fn calculate_sum(numbers: &[i32]) -> i32 {
    numbers.iter().sum()
}
\n

من المعتاد في Rust استخدام snake_case للدوال والمتغيرات، و CamelCase للأنواع والـ Traits. التزم بهذا الأسلوب باستمرار.

\n\n

الهياكل والوحدات

\n

قم بتجميع البيانات المرتبطة في هياكل. هذا يحسن قابلية القراءة ويسمح للمترجم بالتحقق من الصحة.

\n
// سيء: متغيرات متفرقة
let user_name = String::from("أحمد");
let user_age = 30;
let user_email = String::from("ahmed@example.com");

// جيد: هيكل بحقول واضحة
struct User {
    name: String,
    age: u8,
    email: String,
}
let user = User {
    name: String::from("أحمد"),
    age: 30,
    email: String::from("ahmed@example.com"),
};
\n

استخدم الوحدات (modules) لتقسيم الكود منطقيًا. يجب أن تكون كل وحدة مسؤولة عن مجال واحد من المسؤولية (مبدأ المسؤولية الواحدة).

\n\n

المبدأ 2: استخدام نظام الأنواع والـ Traits

\n

نظام الأنواع في Rust هو أداة قوية لكتابة كود موثق ذاتيًا. بدلاً من التعليقات، استخدم الأنواع للتعبير عن النوايا.

\n\n

نمط النوع الجديد (Newtype pattern)

\n

تغليف الأنواع البدائية في هيكل يساعد على تجنب الالتباس ويضيف دلالات.

\n
// سيء: من السهل الخلط بين ترتيب الوسائط
fn set_coordinates(x: f64, y: f64) { /* ... */ }

// جيد: الأنواع تشير بوضوح إلى المعنى
struct Latitude(f64);
struct Longitude(f64);

fn set_coordinates(lat: Latitude, lon: Longitude) { /* ... */ }
\n\n

الـ Traits كعقود

\n

تحدد الـ Traits السلوك. قم بتسميتها بحيث يكون واضحًا الوظيفة التي تقدمها.

\n
// سيء: اسم مجرد
trait Process {
    fn handle(&self);
}

// جيد: الاسم يعكس الإجراء
trait Serialize {
    fn to_json(&self) -> String;
}

// تنفيذ للهيكل
struct Config {
    version: u8,
}

impl Serialize for Config {
    fn to_json(&self) -> String {
        format!("{{\\"version\\": {}}}", self.version)
    }
}
\n

استخدم البرمجة العامة (generics) مع حدود الـ Traits فقط عند الحاجة الفعلية. هذا يجعل الكود مرنًا دون أن يكون مثقلًا.

\n\n

المبدأ 3: معالجة الأخطاء بشكل صحيح

\n

لا توجد استثناءات في Rust، ولكن يوجد نظام قوي Result و Option. يستخدم الكود النظيف هذه الأنظمة بشكل اصطلاحي، متجنبًا الذعر (panic) والـ unwrap() غير الضروري.

\n\n

تجنب unwrap() في كود الإنتاج

\n

unwrap() و expect() مناسبان فقط في النماذج الأولية أو الاختبارات

المدونات

توصيات الكتب