تصحيح أخطاء كود Rust: من «println!» إلى أدوات المحترفين
كل من كتب بلغة Rust لمدة أسبوع على الأقل يعرف هذا الشعور: المترجم سمح، البرنامج تم تجميعه، يتم تشغيله... ويفعل شيئًا غير متوقع تمامًا. أو ببساطة يتعطل مع خطأ غامض Segmentation fault. مرحبًا بك في عالم تصحيح الأخطاء! الخبر السار: في Rust هناك ترسانة كاملة لهذا الغرض - من ماكرو بسيط إلى مصححات أخطاء متقدمة. في هذه المقالة سنستعرض جميع طرق تصحيح أخطاء كود Rust، من الأساسية إلى الاحترافية.
1. المجموعة الأساسية: الماكروات dbg! و eprintln!
لنبدأ بالأسهل والأكثر توفرًا. إذا كنت تكتب كود Rust وتريد فهم ما يحدث في المتغيرات بسرعة - استخدم dbg!. فهو يطبع اسم المتغير وقيمته والملف ورقم السطر. أكثر راحة من println! القديم الجيد.
fn calculate_even_sum(numbers: &[i32]) -> i32 { let mut sum = 0; for &n in numbers { if n % 2 == 0 { sum += n; dbg!(n, sum); // ننظر إلى كل رقم زوجي والمجموع الحالي } } sum}
fn main() { let data = vec![1, 2, 3, 4, 5, 6]; let result = calculate_even_sum(&data); dbg!(result);}شغّل - وسترى شيئًا مثل:
[src/main.rs:6:13] n = 2[src/main.rs:6:13] sum = 2[src/main.rs:6:13] n = 4[src/main.rs:6:13] sum = 6[src/main.rs:6:13] n = 6[src/main.rs:6:13] sum = 12[src/main.rs:12:5] result = 12وإذا كنت بحاجة للكتابة إلى stderr (مثلًا، لتجنب إزعاج stdout عند استخدام الأنابيب) - استخدم eprintln!. هذا لا غنى عنه عند تصحيح أخطاء كود Rust في بيئة الإنتاج.
2. التسجيل المتقدم باستخدام log و env_logger
عندما يكبر المشروع، يصبح نشر dbg! في جميع أنحاء الكود مؤلمًا. هنا تأتي الحزم log و env_logger للإنقاذ. تسمح بتشغيل/إيقاف السجلات دون إعادة التجميع.
use log::{info, warn, error, debug};
fn main() { env_logger::init();
info!("تم تشغيل البرنامج"); let x = 42; debug!("قيمة x: {}", x);
if x > 100 { warn!("x كبير جدًا!"); } else { error!("هذا ليس خطأ، مجرد اختبار"); }}شغّل مع متغير البيئة RUST_LOG=debug cargo run - وستحصل على جميع السجلات. تريد التحذيرات فقط؟ RUST_LOG=warn. مريح جدًا لـ تصحيح أخطاء تطبيقات Rust في الوقت الفعلي.
3. الذعر و backtrace: قراءة مكدس الأخطاء
عندما يصاب البرنامج بالذعر، يقوم Rust بطباعة رسالة. لكن هذا غالبًا لا يكفي. قم بتفعيل backtrace الكامل:
$ RUST_BACKTRACE=1 cargo runأو للحصول على أقصى تفاصيل:
$ RUST_BACKTRACE=full cargo runسترى مكدس الاستدعاءات بالكامل - من نقطة الانهيار إلى main. هذا أمر بالغ الأهمية عند تصحيح أخطاء كود Rust إذا كنت لا تفهم من أين جاء الخطأ.
مثال: لنفترض أن لديك هذا الكود:
fn main() { let v = vec![1, 2, 3]; println!("{}", v[10]); // ذعر!}مع RUST_BACKTRACE=1 سترى ليس فقط "index out of bounds"، بل السطر والاستدعاء الدقيقين.
4. وضع التصحيح والتحسين: debug مقابل release
نقطة مهمة: تصحيح أخطاء كود Rust في وضع debug (الافتراضي) يعطي معلومات كاملة. لكن في وضع release، يقوم المترجم بتحسين الكود، وقد تختفي بعض المتغيرات أو يتغير ترتيبها. إذا كنت تصحح خطأ في "الإصدار" - استخدم ملفًا شخصيًا مع معلومات التصحيح:
[profile.release]debug = trueفي Cargo.toml. سيسمح لك هذا بتشغيل cargo run --release
المدونات
توصيات الكتب
اقرأ أيضًا