الدرس4 / 4
أول برنامج
قراءة
اللي هتفهمه
- إزاي تعمل مشروع بـ cargo، وإيه كل ملف بيتعمل بيعمل إيه.
- الفرق العملي بين cargo build و cargo run و cargo check، وإمتى تستخدم كل واحد.
- فين الملف التنفيذي بيقع، وليه مالوش امتداد على لينكس وماك.
الشرح
تقدر تترجم ملف Rust واحد بـ rustc مباشرة، بس محدش بيعمل كده في مشروع حقيقي.
الأداة اللي هتستخدمها كل يوم هي cargo، وهي مدير مشاريع كامل: بتعمل هيكل
المشروع، بتنزّل التبعيات، بتبني، وبتشغّل الاختبارات.
ابدأ من مجلد مشاريعك واعمل مشروع جديد:
cargo new helloالرد:
Creating binary (application) `hello` package
note: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.htmlcargo 1.97.1 (c980f4866 2026-06-30)
كلمة binary هنا معناها إن ده برنامج بيشتغل، مش مكتبة. لو كنت عايز مكتبة كنت
كتبت cargo new --lib.
خد بالك إن cargo new بيعمل مستودع git جوه المشروع كمان — عشان كده فيه
.gitignore من غير ما تطلبه.
المرئي
الكود
src/main.rs اتعمل جاهز وفيه ده:
fn main() {
println!("Hello, world!");
}افتح في Playgroundأربع حاجات في تلات سطور:
fnبتعرّف دالة.mainاسم خاص: دي نقطة بداية كل برنامج تنفيذي في Rust. لو مش موجودة، الترجمة بتفشل.println!— علامة التعجب دي مش زينة. هي بتقول إن ده ماكرو مش دالة، والفرق مهم: الماكرو بيتوسّع لكود تاني وقت الترجمة، وعشان كده بيقدر ياخد عدد متغير من الوسائط ويتحقق من صيغة النص وقت الترجمة.- الفاصلة المنقوطة في آخر السطر بتخلّيه جملة. الفرق بين الجملة والتعبير حاجة أساسية في Rust، وليها درس كامل بعد كده.
Cargo.toml
[package]
name = "hello"
version = "0.1.0"
edition = "2024"
[dependencies]nameاسم الحزمة، وهو كمان اسم الملف التنفيذي اللي هيطلع.editionإصدار اللغة. Rust بتطلّع إصدار كل تلات سنين، والإصدارات القديمة بتفضل مدعومة للأبد — يعني كودك القديم مش هيقع أبداً. الرقم عندك ممكن يكون مختلف حسب نسخةcargo.[dependencies]فاضي دلوقتي. لما تضيف مكتبة، بتتكتب هنا سطر واحد وcargoبيتولى الباقي.
ليه بيشتغل كده
فيه تلات أوامر هتستخدمهم، وكل واحد ليه سبب وجود مختلف.
cargo run — ابنِ وشغّل
Compiling hello v0.1.0 (/home/user/hello)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.09s
Running `target/debug/hello`
Hello, world!cargo 1.97.1 (c980f4866 2026-06-30)
ده اللي هتستخدمه 90% من الوقت. لاحظ السطر Running — هو بيقولك بالظبط أنهي ملف
شغّله.
cargo build — ابنِ بس
Compiling hello v0.1.0 (/home/user/hello)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.09sبيطلّع الملف ومش بيشغّله.
cargo check — اتأكد إنه بيترجم، من غير ما تبني
Checking hello v0.1.0 (/home/user/hello)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.02sخد بالك من كلمة Checking بدل Compiling، ومن الوقت. cargo check بيعمل كل
التحليل — الأنواع، الملكية، الاستعارة — وبيوقف قبل الخطوة الأغلى، وهي توليد الكود
الفعلي.
في مشروع صغير الفرق مش باين. في مشروع حقيقي، check بيبقى أسرع بمرات كتير،
وده اللي بيخلّيه الأمر اللي بتشغّله وإنت بتكتب. rust-analyzer بيشغّله لوحده وراك
في المحرر — عشان كده بتشوف الأخطاء قبل ما تحفظ.
فين الملف بقى
cargo بيحط كل ناتج البناء في target/، مش جنب src/:
$ ls -F target/debug
build/ deps/ examples/ hello* hello.d incremental/الملف اسمه hello من غير أي امتداد. على لينكس وماك، اللي بيحدد إن الملف تنفيذي
هو بِت الصلاحية x، مش اسمه — علامة * اللي ls -F بيحطها معناها إن البِت ده
مفعّل. على ويندوز بس هتلاقي hello.exe.
وتقدر تشغّله بنفسك:
./target/debug/helloالـ ./ مش زيادة — من غيرها الـ shell بيدوّر في مسارات النظام بس ومش بيبص في
المجلد اللي إنت واقف فيه.
لو دوّرت على الملف وملقتوش، الشرح الكامل في فين الملف التنفيذي بعد cargo build؟.
تمرين
غيّر src/main.rs عشان يطبع اسمك، وبعدين جاوب:
- شغّل
cargo buildمرتين ورا بعض. إيه الفرق في المخرجات بين المرة الأولى والتانية، وليه؟ - شغّل
cargo checkبعد ما تضيف سطر فيه غلط إملائي (مثلاًprintn!). إيه الرسالة؟ - جرّب
cargo build --release. الملف بيقع فين المرة دي؟
الحل
1. المرة الأولى بتشوف Compiling وبعدها Finished. المرة التانية بتشوف
Finished لوحدها، والوقت قريب من الصفر. cargo بيقارن تواريخ تعديل الملفات
وبيعرف إن مفيش حاجة اتغيرت، فمش بيعيد الترجمة. المجلد target/incremental/
موجود عشان الحكاية دي بالظبط.
2. cargo check بيوقف على الغلط ومش بيبني حاجة، فالرد بيبقى أسرع بكتير من
build. جرّب الاتنين وقارن الوقت المكتوب في سطر النهاية.
3. في target/release/hello، مش target/debug/. بناء الـ release بيشغّل
المُحسِّن — أبطأ في الترجمة، أسرع بكتير في التشغيل، وبيشيل معلومات التصحيح.
وفيه فرق تالت أهم من الاتنين دول، هتقابله في درس أنواع البيانات: الفيضان
الحسابي بيتصرّف بشكل مختلف في الاتنين. في debug البرنامج بيقف بخطأ واضح، وفي
release الرقم بيلف. ده مقصود، والدرس اللي جاي بيشرح ليه.
النقاش
لو عندك سؤال أو لقيت غلطة في الصفحة دي، اكتبها فيالنقاشات على GitHub. كل صفحة ليها موضوعها الخاص.