سمة Debug
جزء من قسم البرمجة كائنية التوجه في رحلة Rust على Coddy. الدرس 35 من 61.
تأتي المكتبة القياسية في Rust مع العديد من السمات المُعرَّفة مسبقًا التي توفر وظائف شائعة. ومن أكثرها فائدةً أثناء التطوير سمة Debug، التي تتيح لك طباعة محتويات بنية لفحصها.
إذا حاولت طباعة بنية مخصصة مباشرةً، فلن يعرف Rust كيفية عرضها:
struct Player {
name: String,
score: u32,
}
let p = Player { name: String::from("Alice"), score: 100 };
println!("{:?}", p); // خطأ! Debug غير مُنفَّذ
يتطلب منسّق {:?} سمة Debug. بدلًا من تنفيذها يدويًا، توفّر Rust اختصارًا: السمة #[derive]. ضعها مباشرةً فوق تعريف struct:
#[derive(Debug)]
struct Player {
name: String,
score: u32,
}
let p = Player { name: String::from("Alice"), score: 100 };
println!("{:?}", p); // Player { name: "Alice", score: 100 }
تخبر السمة #[derive(Debug)] المصرّفَ بإنشاء تطبيق Debug تلقائيًا. يعمل هذا ما دامت جميع الحقول في struct الخاص بك تطبّق أيضًا Debug (وهو ما تفعله معظم الأنواع القياسية).
لإخراج أكثر قابلية للقراءة مع البُنى المتداخلة، استخدم {:#?} للطباعة المنسّقة:
println!("{:#?}", p);
// Player {
// name: "Alice",
// score: 100,
// }
اشتقاق Debug أمر ضروري أثناء التطوير. فهو يتيح لك فحص بياناتك بسرعة دون كتابة تعليمات برمجية مخصّصة للتنسيق.
التحدي
سهللنجعل هياكلك قابلة للفحص من خلال اشتقاق سمة Debug! ستنشئ نظام مخزون بسيطًا يمكن فيه طباعة العناصر لأغراض تصحيح الأخطاء.
ستنظّم التعليمات البرمجية عبر ملفين:
inventory.rs: عرّف هيكلItempublic يحتوي على حقلين public: name(String) وquantity(u32). استخدم سمة#[derive(Debug)]لتنفيذ سمة Debug تلقائيًا لهياكلك.main.rs: أضف وحدة inventory وأنشئ نسخةItemباستخدام المدخلات المقدَّمة. اطبع العنصر باستخدام منسّق التصحيح{:?}لعرض بنيته الداخلية.
يكمن جمال اشتقاق Debug في أن Rust تنشئ تلقائيًا تعليمات التنسيق نيابةً عنك: لا حاجة إلى تنفيذ يدوي! يحتاج هيكلك فقط إلى السمة، وبذلك يصبح قابلاً للطباعة باستخدام {:?}.
يجب أن يعرض الناتج العنصر بتنسيق تصحيح Rust:
Item { name: "{name}", quantity: {quantity} }على سبيل المثال، عند استخدام المدخلين Keyboard و15:
Item { name: "Keyboard", quantity: 15 }ستتلقى مدخلين: اسم العنصر والكمية (حلّلها كنوع u32).
جرّب بنفسك
mod inventory;
use inventory::Item;
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 quantity_str = String::new();
std::io::stdin().read_line(&mut quantity_str).expect("Failed to read line");
let quantity: u32 = quantity_str.trim().parse().expect("Failed to parse quantity");
// TODO: أنشئ مثيلاً من Item بالاسم والكمية المعطيين
// TODO: اطبع العنصر باستخدام منسق التصحيح {:?}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الأساليب والسلوك
مقدمة في كتل التنفيذمعامل Selfالأساليب القابلة للتعديلالدوال المرتبطةكتل تنفيذ متعددةتسلسل الأساليبمراجعة - إجراءات المستطيل4مشروع: حيوان أليف افتراضي
تعريف الحيوان الأليفإطعام الحيوان الأليف2التغليف والوحدات البرمجية
أساسيات الوحدات البرمجيةالكلمة المفتاحية Publicالحقول الخاصةدوال Gettersدوال Settersمراجعة - الخزانة الآمنة5الأنواع العامة (Generics)
الـ Structs العامةالـ Methods العامةأنواع عامة متعددةالـ Functions العامةمراجعة - Coordinate Point3التعدادات المتقدمة (Advanced Enums)
التعدادات مع البياناتالأساليب (Methods) في التعداداتمطابقة حالات البياناتمراجعة التعداد Optionملخص - التعداد Shape6تعريف الـ Traits
ما هي الـ Trait؟تنفيذ الـ Traitsالتنفيذات الافتراضيةتجاوز التنفيذات الافتراضيةالـ Traits مع المعاملاتملخص - مشغل الوسائطتدرّب بنفسك: مترجم Rust عبر الإنترنت