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

سمة Display

جزء من قسم Object Oriented Programming في رحلة Rust على Coddy — الدرس 36 من 61.

بينما تُعد Debug رائعة للمطورين الذين يفحصون البيانات، فإن سمة Display مُصممة لـ المخرجات الموجهة للمستخدم. وهي ما يشغل المنسق {} في println!. وعلى عكس Debug، لا يمكن لـ Rust اشتقاق Display تلقائيًا—يجب عليك تنفيذها يدويًا.

لتنفيذ Display، تحتاج إلى استيراد وحدة fmt وتنفيذ دالة fmt:

use std::fmt;

struct Temperature {
    celsius: f64,
}

impl fmt::Display for Temperature {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}°C", self.celsius)
    }
}

تستقبل طريقة fmt كائن Formatter وتُرجع fmt::Result. تستخدم ماكرو write! لتنسيق مخرجاتك، مع الوصول إلى حقول الهيكل (struct) من خلال self.

يمكنك الآن طباعة الـ struct باستخدام المنسق القياسي {}:

let temp = Temperature { celsius: 23.5 };
println!("{}", temp);  // 23.5°C

الفرق الرئيسي: يُظهر مخرج Debug هيكلية بياناتك (مفيد لتصحيح الأخطاء)، بينما مخرج Display يكون منسقاً ومخصصاً للمستخدمين النهائيين. يمكن للـ struct تنفيذ كليهما—استخدم {:?} لتصحيح الأخطاء و {} للحصول على مخرجات نظيفة.

challenge icon

التحدي

سهل

لنقم بإنشاء نظام عرض منتجات سهل الاستخدام! بينما تُظهر سمة Debug البنية الخام لبياناتك، تتيح لك سمة Display صياغة مخرجات مصقولة وقابلة للقراءة من قبل البشر، وهي مثالية للمستخدمين النهائيين.

ستقوم بتنظيم الكود الخاص بك عبر ملفين:

  • product.rs: قم بتعريف هيكل Product عام مع حقلين عامين: name (String) و price (f64). قم بتنفيذ سمة Display لهيكلك بحيث يتم تنسيقه كـ {name} - ${price}. تذكر استيراد std::fmt واستخدام ماكرو write! داخل تابع fmt الخاص بك.
  • main.rs: قم باستيراد وحدة المنتج الخاصة بك وأنشئ مثيلاً من Product باستخدام المدخلات المقدمة. اطبع المنتج باستخدام منسق {} القياسي لعرض مخرجات العرض المخصصة الخاصة بك.

تتطلب سمة Display منك تنفيذ تابع fmt يدويًا—لا يمكن لـ Rust اشتقاقه تلقائيًا مثل Debug. يمنحك هذا تحكمًا كاملاً في كيفية ظهور نوع بياناتك للمستخدمين.

يجب أن يعرض مخرجك المنتج بتنسيق نظيف وسهل الاستخدام:

{name} - ${price}

على سبيل المثال، مع المدخلات Wireless Mouse و 29.99:

Wireless Mouse - $29.99

ستتلقى مدخلين: اسم المنتج والسعر (قم بتحليله كـ f64).

ورقة مرجعية

تم تصميم سمة (trait) الـ Display من أجل المخرجات الموجهة للمستخدم وهي التي تشغل منسق {} في println!. وعلى عكس Debug، يجب تنفيذها يدوياً.

لتنفيذ Display، قم باستيراد وحدة fmt ونفذ دالة fmt:

use std::fmt;

struct Temperature {
    celsius: f64,
}

impl fmt::Display for Temperature {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}°C", self.celsius)
    }
}

تستقبل دالة fmt كائن Formatter وتُرجع fmt::Result. استخدم ماكرو write! لتنسيق المخرجات، مع الوصول إلى حقول الهيكل (struct) عبر self.

اطبع الهيكل باستخدام منسق {}:

let temp = Temperature { celsius: 23.5 };
println!("{}", temp);  // 23.5°C

الفرق الرئيسي: تعرض Debug ({:?}) هيكل البيانات لأغراض تصحيح الأخطاء، بينما توفر Display ({}) مخرجات منسقة للمستخدمين النهائيين.

جرّب بنفسك

mod product;

use product::Product;

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

    let mut price_input = String::new();
    std::io::stdin().read_line(&mut price_input).expect("Failed to read line");
    let price: f64 = price_input.trim().parse().expect("Failed to parse price");

    // TODO: إنشاء مثيل (instance) من Product باستخدام الاسم والسعر

    // TODO: طباعة المنتج باستخدام المنسق {}
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming