Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

جملة Where

جزء من قسم البرمجة كائنية التوجه في رحلة Rust على Coddy. الدرس 42 من 61.

مع إضافة المزيد من قيود السمات، قد تصبح تواقيع الدوال صعبة القراءة. تأمل دالة تحتوي على عدة معاملات عامة، يتطلب كل منها عدة سمات:

fn complex_operation<T: Display + Clone, U: Debug + Summary>(first: T, second: U) {
    // ...
}

هذا يعمل، لكن التوقيع أصبح مزدحمًا. يقدّم where بديلاً أكثر وضوحًا من خلال نقل حدود السمات إلى ما بعد قائمة المعاملات:

fn complex_operation<T, U>(first: T, second: U)
where
    T: Display + Clone,
    U: Debug + Summary,
{
    // ...
}

الإصداران متطابقان وظيفيًا: فقرة where تتعلق فقط بسهولة القراءة. تظهر متطلبات كل نوع في سطر مستقل، مما يسهّل الاطلاع على ما يحتاج إليه كل مُعامل عام.

يصبح بند where ذا قيمة خاصة عندما تكون القيود معقدة أو عندما يكون لديك العديد من المعاملات العامة. فهو يُبقي اسم الدالة والمعاملات ظاهرين بنظرة سريعة، مع إدراج القيود بشكل منفصل أدناه. وهذا هو الأسلوب المفضّل في معظم قواعد Rust البرمجية عندما تتجاوز القيود صيغة بسيطة مثل T: Trait.

challenge icon

التحدي

سهل

لنبنِ نظامًا لمعالجة البيانات يستخدم where clause للحفاظ على قابلية قراءة حدود السمات المعقدة! ستنشئ generic function تحتوي على معاملات نوع متعددة، ويتطلب كل منها سمات مختلفة، وستنظم الحدود بشكل واضح باستخدام صيغة where.

ستنظم شيفرتك عبر ملفين:

  • processor.rs: عرّف سمتين public وgeneric function تستخدمهما معًا:
    • Summarize: سمة تحتوي على summary method تأخذ &self وتُرجع String
    • Validate: سمة تحتوي على validate method تأخذ &self وتُرجع bool
    ثم أنشئ public generic function تُسمى process_items وتقبل معاملين من نوعين عامّين مختلفين. استخدم عبارة where لتحديد أن النوع الأول يجب أن يطبّق كلًا من Clone وSummarize، بينما يجب أن يطبّق النوع الثاني Validate. يجب أن تطبع function ملخص العنصر الأول، ثم تطبع ما إذا كان العنصر الثاني صالحًا.
  • main.rs: أنشئ بنيتين public تطبّقان السمات المطلوبة:
    • Article: تحتوي على title field public (String). طبّق Summarize لإرجاع Article: {title}، واشتق Clone.
    • Form: تحتوي على filled field public (bool). طبّق Validate لإرجاع قيمة filled.
    استخدم المدخلات المقدمة لإنشاء Article وForm، ثم استدعِ process_items باستخدام كليهما.

تجعل عبارة where توقيع function أنظف بكثير من حشر جميع الحدود داخل الأقواس الزاوية. تظهر متطلبات كل نوع في سطره الخاص، مما يسهّل رؤية ما يحتاج إليه كل معامل generic.

يجب أن يُظهر ناتجك الملخص متبوعًا بنتيجة التحقق:

Article: {title}
Valid: {true/false}

على سبيل المثال، باستخدام المدخلين Rust Tips وtrue:

Article: Rust Tips
Valid: true

وباستخدام المدخلين Breaking News وfalse:

Article: Breaking News
Valid: false

ستتلقى مدخلين: عنوان المقالة وما إذا كان النموذج مملوءًا (حلّله باعتباره bool).

جرّب بنفسك

mod processor;

use processor::{Summarize, Validate, process_items};
use std::io;

// TODO: عرّف struct عام Article مع حقل title عام (String)
// اشتق Clone لـ Article

// TODO: نفّذ Summarize لـ Article
// يجب أن تُرجع الدالة summary القيمة "Article: {title}"

// TODO: عرّف struct عام Form مع حقل filled عام (bool)

// TODO: نفّذ Validate لـ Form
// يجب أن تُرجع الدالة validate قيمة filled

fn main() {
    let mut title = String::new();
    io::stdin().read_line(&mut title).expect("Failed to read line");
    let title = title.trim().to_string();

    let mut filled_input = String::new();
    io::stdin().read_line(&mut filled_input).expect("Failed to read line");
    let filled: bool = filled_input.trim().parse().expect("Failed to parse bool");

    // TODO: أنشئ Article بالعنوان المعطى
    
    // TODO: أنشئ Form بقيمة filled المعطاة
    
    // TODO: استدعِ process_items مع الـ article والـ form
}
quiz iconاختبر نفسك

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

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم Rust عبر الإنترنت