Rust: نظام الوحدات في لغة Rust و«Cargo»
آخر تحديث: 2026-08-26
نظام الوحدات النمطية هو «نظام تحديد مواقع الكود» في لغة Rust — تمامًا مثل عنوان مبنى ما في الشارع، فهو يتيح لك تحديد موقع كل جزء من الكود بدقة والتحكم في أجزاء الكود التي يمكن الوصول إليها من الخارج.
لو كان المشروع الكبير مدينة، لكان كل وحدة (mod) بمثابة حي، وكل ملف بمثابة مبنى، وكل دالة بمثابة غرفة. أما «Cargo» فهي إدارة المدينة — المسؤولة عن شق الطرق، وإجراء أعمال الصيانة، وضمان الجودة. وبدون نظام الوحدات، لكان الكود عبارة عن خليط من «القرى الحضرية».
1. ما ستتعلمه
modوحدات تعريف الكلمات المفتاحية والوحدات المتداخلةpubالتحكم في الرؤية — قواعد الوصول للوحدات النمطية الأصلية والتابعة والمتساويةuseاستيراد المسار وsuper/crateالمسارات النسبيةCargo.tomlإدارة التبعيات والترقيم الدلالي (SemVer)cargo build/test/bench/docالأوامر المشتركة- إدارة الحزم المتعددة في مساحة العمل وتقسيم المهام بين
lib.rsوmain.rs
2. القصة وراء نظام ترقيم الشقق
(1) المعاناة: مدينة بلا أرقام للمنازل
انتقل توم إلى مبنى سكني تم تشييده حديثًا واكتشف أنه لا يوجد فيه نظام لترقيم المنازل.
- كان يبحث عن الغرفة 502 في المبنى 3، لكن جميع المباني كانت متشابهة.
- عند توصيل الطعام، يتعين على سائقي التوصيل الاتصال بالسائقين والسؤال: «في أي مبنى أنت؟»
- إشعار من إدارة العقار: «يرجى النزول لاستلام طردكم، سكان الوحدة 3، الطابق الخامس» — لكن هناك في الواقع ست أسر في الطابق الخامس من الوحدة 3.
- وما زاد الطين بلة أن السكان الجدد غيّروا رقم منزلهم إلى «ألي بابا» — فانهار نظام العناوين برمته.
«سيكون من الرائع لو كان هناك نظام موحد لترقيم المنازل: المبنى - الوحدة - الشقة...»
(2) مناهج نظام الوحدات في لغة Rust
Apartment(Crate) → A building
Building Name(crate name) → Building Number
Unit(Module) → Apartment Building Entrance
Room Number(Function) → Specific Rooms
// File Structure Correspondence:
// src/
// main.rs → Apartment Lobby(Entrance)
// building/
// mod.rs → Building Information
// unit_1/
// mod.rs → 1 Unit
// room_501.rs → 501 Room
// room_502.rs → 502 Room
// In Rust, through mod and pub, precisely control who can access what
mod building {
pub mod unit_1 {
pub fn room_501() -> &'static str {
"501 Room: Tom Home"
}
fn room_502() -> &'static str {
"502 Room: Private Space" // Default: Private, not visible externally
}
}
}
fn main() {
// Access via the full path
println!("{}", building::unit_1::room_501());
// println!("{}", building::unit_1::room_502()); // ❌ Private Functions,Compilation Error
}
يشبه نظام الوحدات في لغة «Rust» نظام العناوين في مبنى سكني: يمثل
crateالمبنى بأكمله، ويمثلmodالوحدة السكنية، ويمثلfnالشقة. ويحددpubالشقق التي لها أبواب تفتح على الخارج؛ أما الشقق التي لا تحتوي علىpubفهي خاصة — ولا يمكن للأشخاص من خارج المبنى دخولها بحرية.
3. المفاهيم الأساسية
(1) نظام الوحدات والمسارات
graph TB
A[Rust Modular System] --> B[mod Definition]
A --> C[pub Visibility]
A --> D[use Path Import]
A --> E[Cargo Project Management]
B --> B1["mod Module Name { ... }"]
B --> B2["mod Module Name; // From a file"]
C --> C1["pub: Visible to the public"]
C --> C2["pub(crate): crate only, visible inside"]
C --> C3["pub(super): Visible only to the parent module"]
C --> C4["No pub: Private"]
D --> D1["use crate::a::b::c;"]
D --> D2["use super::module;"]
D --> D3["use self::module;"]
E --> E1["Cargo.toml Dependency"]
E --> E2["cargo build / test"]
E --> E3["workspace Multiple Packages"]
E --> E4["lib.rs vs main.rs"]
(2) مقارنة قواعد الرؤية
| الرؤية | الكلمات المفتاحية | من يمكنه الوصول | التشبيه |
|---|---|---|---|
| خاص | لا شيء (الافتراضي) | الوحدة الحالية والوحدات الفرعية | لا يُسمح بدخول غرفة النوم إلا لأفراد الأسرة |
| مرئي للوحدة الأم | pub(super) |
الوحدة الأم | يمكن للجيران في الطابقين العلوي والسفلي زيارتنا |
| مرئي داخل الصندوق | pub(crate) |
جميع الوحدات الموجودة في الصندوق الحالي | يمكن للمقيمين دخول بوابة المجمع |
| عام | pub |
جميع الصناديق الخارجية | يمكن لأي شخص دخول المركز التجاري |
(3) أنواع المسارات
| نوع المسار | البادئة | مثال | الوصف |
|---|---|---|---|
| المسار المطلق | crate:: |
crate::utils::helper::foo |
بدءًا من جذر الصندوق |
| المسار النسبي | self:: |
self::helper::foo |
بدءًا من الوحدة الحالية |
| المسار النسبي | super:: |
super::helper::foo |
بدءًا من الوحدة النمطية الأم |
| المسار الخارجي | اسم الحزمة | serde::Serialize |
بدءًا من كريت خارجي |
(4) مرجع سريع لأوامر الشحن الشائعة
| الأمر | الوظيفة | الخيارات الشائعة |
|---|---|---|
cargo new |
إنشاء مشروع جديد | --lib (مشروع مكتبة) |
cargo build |
ترجمة المشروع | --release (ترجمة مُحسَّنة) |
cargo run |
التجميع والتشغيل | --bin name (تحديد الملف الثنائي) |
cargo check |
التحقق السريع من أخطاء الترجمة | أسرع من عملية البناء؛ ولا يُنتج ملفات ثنائية |
cargo test |
تشغيل الاختبار | test_name (اختبار محدد) |
cargo doc |
إنشاء مستند | --open (يفتح المتصفح تلقائيًا) |
cargo clippy |
فحوصات lint للكود | -W clippy::all |
cargo fmt |
تنسيق الكود | --check (للمراجعة فقط، لا تقم بالتعديل) |
cargo add |
إضافة تبعية | --features xxx |
cargo update |
تحديث ملف قفل التبعيات | تحديث ملف Cargo.lock |
cargo publish |
النشر على crates.io | يجب تسجيل الدخول أولاً |
cargo clean |
تنظيف ملفات البناء | حذف المجلد target/ |
4. أمثلة على الوحدات النمطية و«Cargo»
(1) ▶ المثال:تعريفات الوحدات النمطية ومدى ظهور pub (مستوى الصعوبة ⭐)
// ============================================
// Module Nesting、pub Visibility、Path Access
// Demo: The restaurant's kitchen is not visible to customers, but visible to servers
// ============================================
// Defining the Restaurant Module
mod restaurant {
// Public: Customers may enter the restaurant
pub struct Menu {
pub name: String,
price: f64, // Default: Private,Not visible externally
}
impl Menu {
// Public Constructor
pub fn new(name: &str, price: f64) -> Menu {
Menu {
name: name.to_string(),
price,
}
}
// Public Methods: Get Price
pub fn get_price(&self) -> f64 {
self.price
}
}
// Public: Customers can order food
pub fn order_food(item: &str) -> String {
// Private: Kitchen operations are not visible to customers
let prepared = prepare_in_kitchen(item);
format!("Your {} Ready: {}", item, prepared)
}
// Private: Customers are not allowed in the kitchen.
fn prepare_in_kitchen(item: &str) -> String {
format!("[Kitchen] {} Cooking in progress...", item)
}
// Nested Modules: Inside the Kitchen
mod kitchen {
// Private Storage Area
pub struct Storage {
pub items: Vec<String>,
}
impl Storage {
pub fn new() -> Storage {
Storage {
items: vec![
"Vegetables".to_string(),
"Meat".to_string(),
"Seasonings".to_string(),
],
}
}
}
}
}
fn main() {
// Accessing Public Module Members
let dish = restaurant::order_food("Kung Pao Chicken");
println!("{}", dish);
// Create a public struct
let menu_item = restaurant::Menu::new("Kung Pao Chicken", 38.0);
println!("Dishes: {}, Price: {:.1} yuan", menu_item.name, menu_item.get_price());
// The following code cannot be compiled(Uncomment this line to try it):
// println!("Chef Information: {}", restaurant::prepare_in_kitchen("Kung Pao Chicken")); // ❌ Private Functions
// println!("Price: {}", menu_item.price); // ❌ Private Fields
// let storage = restaurant::kitchen::Storage::new(); // ❌ kitchen The module is private.
}
الناتج:
Your Kung Pao Chicken Ready: [Kitchen] Kung Pao Chicken Cooking in progress...
Dishes: Kung Pao Chicken, Price: 38.0 yuan
قواعد رؤية الوحدات تشبه التصميم المادي لمطعم: لا يمكن للعملاء (الكود الخارجي) الدخول إلا إلى قاعة الطعام (وحدة
pub) ولا يمكنهم الدخول إلى المطبخ (الوحدات الخاصة). العمليات التي تجري في المطبخ (prepare_in_kitchen) غير مرئية تمامًا للعالم الخارجي — وهذا هو ما يُعرف بالتغليف.
(2) ▶ المثال:مسارات use وsuper/crate (مستوى الصعوبة: ⭐⭐)
// ============================================
// use Keyword Import Path、super and crate Relative Path
// Simulation: Company Organizational Structure - Department→Group→Employees
// ============================================
// Top-Level Module: Company
mod company {
// Engineering Department
pub mod engineering {
pub fn team_name() -> &'static str {
"Engineering Department"
}
// Front-End Team
pub mod frontend {
pub fn member_count() -> u32 {
5
}
// Use super to access the parent module (engineering)
pub fn full_info() -> String {
format!("{} Front-End Team, {} people", super::team_name(), member_count())
}
}
// Backend Team
pub mod backend {
pub fn member_count() -> u32 {
8
}
// Usage super Access the Parent Module
pub fn full_info() -> String {
format!("{} Backend Team, {} people", super::team_name(), member_count())
}
}
}
// Marketing Department
pub mod marketing {
pub fn team_name() -> &'static str {
"Marketing Department"
}
// Usage crate Path Access from the Root
pub fn total_employees() -> u32 {
// From crate root, access begins
crate::company::engineering::frontend::member_count()
+ crate::company::engineering::backend::member_count()
+ self::member_count()
}
fn member_count() -> u32 {
6
}
}
}
// Usage use Import Path——Simplify the call
use company::engineering::frontend;
use company::engineering::backend;
use company::marketing;
fn main() {
// Method 1: Full path (Not recommended, too long to write)
println!("{}", company::engineering::frontend::full_info());
// Method 2: Call directly after use import (Recommended)
println!("{}", frontend::full_info());
println!("{}", backend::full_info());
// Introduction marketing Module
println!("Number of employees in the Marketing Department: {}", marketing::member_count());
// Usage crate Path Access
println!("Total Number of Employees: {}", marketing::total_employees());
// Usage as Avoiding Alias Conflicts
use company::engineering as eng;
println!("Department: {}", eng::team_name());
}
الناتج:
Engineering Department Front-End Team, 5 people
Engineering Department Backend Team, 8 people
Number of employees in the Marketing Department: 6
Total Number of Employees: 19
Department: Engineering Department
useالأمر أشبه بإنشاء اختصار لـ«رقم المنزل» — حتى لا تضطر إلى كتابة العنوان الكامل في كل مرةcompany::engineering::frontend::full_info().superتعني «الصعود مستوى واحدًا» (الوحدة النمطية الأصلية)، وcrateتعني «العودة إلى مدخل المبنى» (جذر الصندوق).asيمكن استخدام الكلمات المفتاحية كأسماء مستعارة للمسارات، مما يحل التعارضات الناتجة عن تكرار الأسماء.
(3) ▶ المثال:إدارة التبعيات وهيكل المشروع في ملف Cargo.toml (مستوى الصعوبة: ⭐⭐)
// ============================================
// Simulation Cargo Project Structure + Dependency Management
// Demo:lib.rs and main.rs Division of Labor、Using External Dependencies
// ============================================
// Note: This example demonstrates the code in lib.rs
// Actual Cargo.toml See the note below for the contents of the document.
// ============================================
// Cargo.toml Content (Simulation):
// ============================================
// [package]
// name = "my-toolkit"
// version = "0.1.0"
// edition = "2021"
//
// [dependencies]
// serde = { version = "1.0", features = ["derive"] }
// serde_json = "1.0"
// chrono = "0.4"
// regex = "1.10"
//
// [dev-dependencies]
// rand = "0.8"
//
// [profile.release]
// opt-level = 3
// ============================================
// Tools Module: Date Handling
pub mod date_utils {
pub fn format_today() -> String {
// Used in actual projects chrono::Local::now()
"2026-07-03".to_string()
}
pub fn is_weekend(day: &str) -> bool {
day.ends_with("Saturday") || day.ends_with("Sunday")
}
}
// Tools Module: String Processing
pub mod string_utils {
/// Verify the email address format (Simulating Regular Expression Matching)
pub fn validate_email(email: &str) -> bool {
// Simplified Verification: Use regex crate in practice
email.contains('@') && email.contains('.')
}
/// Remove non-alphanumeric characters (Simulation)
pub fn sanitize(input: &str) -> String {
input.chars()
.filter(|c| c.is_alphanumeric() || *c == ' ')
.collect()
}
}
// Tools Module: Mathematical Calculations
pub mod math_utils {
/// Calculate the nth term of the nth term of the Fibonacci sequence
pub fn fibonacci(n: u32) -> u64 {
match n {
0 => 0,
1 => 1,
_ => fibonacci(n - 1) + fibonacci(n - 2),
}
}
/// Determining Whether a Number Is Prime
pub fn is_prime(n: u32) -> bool {
if n < 2 {
return false;
}
let limit = (n as f64).sqrt() as u32;
for i in 2..=limit {
if n % i == 0 {
return false;
}
}
true
}
}
// Test Module (Using #[cfg(test)] Conditional Compilation)
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validate_email() {
assert!(string_utils::validate_email("user@example.com"));
assert!(!string_utils::validate_email("invalid"));
}
#[test]
fn test_fibonacci() {
assert_eq!(math_utils::fibonacci(0), 0);
assert_eq!(math_utils::fibonacci(1), 1);
assert_eq!(math_utils::fibonacci(10), 55);
}
#[test]
fn test_is_prime() {
assert!(math_utils::is_prime(17));
assert!(!math_utils::is_prime(1));
assert!(!math_utils::is_prime(4));
}
#[test]
fn test_sanitize() {
assert_eq!(string_utils::sanitize("hello@world!"), "hello world");
}
}
// ============================================
// main.rs The code in (Simulation):
// ============================================
// use my_toolkit::{
// date_utils,
// string_utils,
// math_utils,
// };
//
// fn main() {
// println!("Today's Date: {}", date_utils::format_today());
// println!("Email Verification: {}", string_utils::validate_email("test@example.com"));
// println!("Prime Number Check: {}", math_utils::is_prime(17));
// }
fn main() {
// Demonstration of Each Tool's Functions
println!("=== Tool Library Demo ===");
// Date Tools
println!("Today: {}", date_utils::format_today());
println!("Is it the weekend?: {}", date_utils::is_weekend("Saturday"));
// String Tools
println!("Email Verification test@example.com: {}", string_utils::validate_email("test@example.com"));
println!("Email Verification invalid: {}", string_utils::validate_email("invalid"));
println!("Purification 'hello@world!': {}", string_utils::sanitize("hello@world!"));
// Mathematical Tools
println!("Fibonacci #10: {}", math_utils::fibonacci(10));
println!("17 Is it a prime number?: {}", math_utils::is_prime(17));
println!("4 Is it a prime number?: {}", math_utils::is_prime(4));
println!("=== End of Presentation ===");
// Instructions for Running the Test (Use cargo test in actual projects)
println!("Usage `cargo test` Run Unit Tests");
}
الناتج:
=== Tool Library Demo ===
Today: 2026-07-03
Is it the weekend?: true
Email Verification test@example.com: true
Email Verification invalid: false
Purification 'hello@world!': hello world
Fibonacci #10: 55
17 Is it a prime number?: true
4 Is it a prime number?: false
=== End of Presentation ===
Usage `cargo test` Run Unit Tests
الهيكل القياسي للمشاريع الفعلية:
lib.rsيحتوي على كود المكتبة (واجهة برمجة التطبيقات العامة)، وmain.rsيحتوي على نقطة الدخول للملف القابل للتنفيذ (الذي يستخدم المكتبة).Cargo.tomlيدير التبعيات، و[dependencies]يحتوي على تبعيات الإنتاج، و[dev-dependencies]يحتوي على تبعيات أدوات الاختبار/البناء.cargo testيكتشف ويُشغّل تلقائيًا الوظائف المُعلَّمة بـ#[test].
(4) ▶ المثال:الأوامر ومساحات العمل الشائعة في «Cargo» (مستوى الصعوبة ⭐⭐⭐)
// ============================================
// Cargo Common Commands and workspace Multi-Package Management
// Simulation: One "Task Manager" workspace Project
// ============================================
// ============================================
// Top Floor Cargo.toml (workspace):
// ============================================
// [workspace]
// members = [
// "task-core", // Core Library
// "task-cli", // CLI Tools
// "task-web", // Web Interface
// ]
//
// [workspace.package]
// version = "1.0.0"
// edition = "2021"
// ============================================
// ============================================
// task-core/Cargo.toml:
// ============================================
// [package]
// name = "task-core"
// version.workspace = true
// edition.workspace = true
//
// [dependencies]
// serde = { version = "1.0", features = ["derive"] }
// chrono = "0.4"
// ============================================
// Simulation task-core Library code
pub mod task_core {
use std::collections::HashMap;
/// Task Priority
#[derive(Debug, Clone, PartialEq)]
pub enum Priority {
Low,
Medium,
High,
Urgent,
}
/// Task Status
#[derive(Debug, Clone, PartialEq)]
pub enum Status {
Todo,
InProgress,
Done,
Cancelled,
}
/// Core Task Structure
#[derive(Debug, Clone)]
pub struct Task {
pub id: u64,
pub title: String,
pub priority: Priority,
pub status: Status,
pub tags: Vec<String>,
}
impl Task {
pub fn new(id: u64, title: &str, priority: Priority) -> Task {
Task {
id,
title: title.to_string(),
priority,
status: Status::Todo,
tags: Vec::new(),
}
}
pub fn add_tag(&mut self, tag: &str) {
self.tags.push(tag.to_string());
}
pub fn is_completed(&self) -> bool {
self.status == Status::Done || self.status == Status::Cancelled
}
}
/// Task Manager
pub struct TaskManager {
tasks: HashMap<u64, Task>,
next_id: u64,
}
impl TaskManager {
pub fn new() -> TaskManager {
TaskManager {
tasks: HashMap::new(),
next_id: 1,
}
}
pub fn create_task(&mut self, title: &str, priority: Priority) -> u64 {
let id = self.next_id;
self.next_id += 1;
let task = Task::new(id, title, priority);
self.tasks.insert(id, task);
id
}
pub fn get_task(&self, id: u64) -> Option<&Task> {
self.tasks.get(&id)
}
pub fn complete_task(&mut self, id: u64) -> bool {
if let Some(task) = self.tasks.get_mut(&id) {
task.status = Status::Done;
true
} else {
false
}
}
pub fn list_tasks(&self) -> Vec<&Task> {
let mut tasks: Vec<&Task> = self.tasks.values().collect();
tasks.sort_by_key(|t| t.id);
tasks
}
}
}
// ============================================
// Cargo Command Reference (Demonstrated in the comments):
// ============================================
// Common Commands:
// cargo new project_name -- Create a New Project
// cargo build -- Compilation (debug)
// cargo build --release -- Compilation (release optimization)
// cargo run -- Compilation + Run
// cargo check -- Quickly Check for Compilation Errors (No binary files generated)
// cargo test -- Run Test
// cargo test test_name -- Run the specified test
// cargo bench -- Run Performance Benchmarks
// cargo doc --open -- Generate the document and open it
// cargo clippy -- Code lint Inspection
// cargo fmt -- Code Formatting
// cargo add crate_name -- Add Dependencies
// cargo update -- Update Dependencies
// cargo publish -- Post to crates.io
// cargo clean -- Clean up compilation output
//
// Workspace Commands:
// cargo build --workspace -- Compilation workspace All packages in
// cargo test -p task-core -- Test only the specified package
// cargo run -p task-cli -- Run the specified package
fn main() {
use task_core::{Priority, TaskManager};
println!("=== Task Manager (Simulation Workspace Project) ===");
let mut manager = TaskManager::new();
// Create a Task
let id1 = manager.create_task("Study Rust Smart Pointers", Priority::High);
let id2 = manager.create_task("Complete the module system exercises", Priority::Medium);
let id3 = manager.create_task("Restore the Production Environment Bug", Priority::Urgent);
// List all tasks
println!("\n--- All Tasks ---");
for task in manager.list_tasks() {
println!("#{} [{:?}] {} - {:?}", task.id, task.priority, task.title, task.status);
}
// Complete a task
manager.complete_task(id1);
println!("\nDone #{} after:", id1);
for task in manager.list_tasks() {
let status = if task.is_completed() { "Completed" } else { "In progress" };
println!("#{} {} - {}", task.id, task.title, status);
}
// Get a Single Task
if let Some(task) = manager.get_task(id3) {
println!("\nUrgent Task: #{} {} ({:?})", task.id, task.title, task.priority);
}
println!("\n=== End of Presentation ===");
println!("Project Structure: task-core (Library) + task-cli (CLI) + task-web (Web)");
println!("Usage `cargo test -p task-core` Testing the Core Library");
println!("Usage `cargo doc --open` Generate Document");
}
الناتج:
=== Task Manager (Simulation Workspace Project) ===
--- All Tasks ---
#1 [High] Study Rust Smart Pointers - Todo
#2 [Medium] Complete the module system exercises - Todo
#3 [Urgent] Restore the Production Environment Bug - Todo
Done #1 after:
#1 Study Rust Smart Pointers - Completed
#2 Complete the module system exercises - In progress
#3 Restore the Production Environment Bug - In progress
Urgent Task: #3 Restore the Production Environment Bug (Urgent)
=== End of Presentation ===
Project Structure: task-core (Library) + task-cli (CLI) + task-web (Web)
Usage `cargo test -p task-core` Testing the Core Library
Usage `cargo doc --open` Generate Document
«Workspace» هي أداة قوية لإدارة المشاريع متعددة الحزم: توفر
task-coreالأنواع والمنطق الأساسي (المكتبات)، وتوفرtask-cliواجهة سطر الأوامر (ملف قابل للتنفيذ)، وتوفرtask-webواجهة برمجة التطبيقات على الويب (ملف قابل للتنفيذ آخر)، بينما تقومcargo build --workspaceبترجمة جميع الحزم دفعة واحدة.cargo test -p task-coreيختبر المكتبات الأساسية فقط.
(5) ▶ المثال:تمرين شامل — محاكاة التصميم المعياري (مستوى الصعوبة ⭐⭐⭐)
// ============================================
// Comprehensive Example: Module Visibility and API Design
// Simulating a Multi-File Project Structure (Actual projects should be broken down into separate files.)
// ============================================
mod math_utils {
pub fn add(a: i32, b: i32) -> i32 { a + b }
pub fn multiply(a: i32, b: i32) -> i32 { a * b }
fn internal_check(val: i32) -> bool { val >= 0 }
pub fn safe_divide(a: i32, b: i32) -> Option<i32> {
if b == 0 { return None; }
if !internal_check(a) || !internal_check(b) { return None; }
Some(a / b)
}
pub mod constants {
pub const PI: f64 = 3.14159265358979;
pub const E: f64 = 2.71828182845905;
pub const MAX_I32: i32 = i32::MAX;
}
}
mod string_utils {
pub fn capitalize(s: &str) -> String {
let mut chars = s.chars();
match chars.next() {
None => String::new(),
Some(first) => first.to_uppercase().collect::<String>() + chars.as_str(),
}
}
pub fn truncate(s: &str, max_len: usize) -> String {
if s.len() <= max_len { s.to_string() }
else { format!("{}...", &s[..max_len.min(s.len())]) }
}
}
mod user {
pub struct User {
pub name: String,
age: u8,
email: String,
}
impl User {
pub fn new(name: &str, age: u8, email: &str) -> Self {
User { name: name.to_string(), age, email: email.to_string() }
}
pub fn age(&self) -> u8 { self.age }
pub fn summary(&self) -> String {
format!("{} ({} years old, {})", self.name, self.age, self.email)
}
}
}
fn main() {
use math_utils::{add, multiply, safe_divide, constants};
use string_utils::{capitalize, truncate};
use user::User;
println!("=== math_utils Module ===");
println!("2 + 3 = {}", add(2, 3));
println!("4 * 5 = {}", multiply(4, 5));
println!("10 / 3 = {:?}", safe_divide(10, 3));
println!("10 / 0 = {:?}", safe_divide(10, 0));
println!("PI = {:.5}, E = {:.5}", constants::PI, constants::E);
println!("\n=== string_utils Module ===");
println!("capitalize: '{}'", capitalize("rust"));
println!("truncate: '{}'", truncate("Hello, World!", 8));
println!("\n=== user Module ===");
let alice = User::new("Alice", 30, "alice@example.com");
println!("{}", alice.summary());
println!("Age: {}", alice.age());
}
الناتج:
=== math_utils Module ===
2 + 3 = 5
4 * 5 = 20
10 / 3 = Some(3)
10 / 0 = None
PI = 3.14159, E = 2.71828
=== string_utils Module ===
capitalize: 'Rust'
truncate: 'Hello, ...'
=== user Module ===
Alice (30 years old, alice@example.com)
Age: 30
المبادئ الثلاثة للتصميم المعياري:
pubلا تُكشف سوى واجهات برمجة التطبيقات (API) الضرورية (مثلaddوsafe_divide)، مع الحفاظ على سرية التفاصيل الداخلية (مثلinternal_check)؛ يتم عرض الوحدات الفرعية (مثلconstants) عبرpub mod؛ ويتم توضيح حقول البنية بشكل فردي مع تحديد مستوى الرؤية (خاصpub name/age+age()getter).
❓ أسئلة شائعة
mod وfn؟ لماذا لا يتم تنظيمهما باستخدام الملفات؟mod هو تعريف وحدة نمطية، وfn هو تعريف دالة.pub(crate) وpub؟pub(crate) مرئي فقط للكود الموجود داخل نفس الكريت، بينما pub مرئي لجميع الكريتات الخارجية.use super::xxx وuse crate::xxx؟super للوصول إلى الوحدة النمطية الأصلية (المسار النسبي)، ويُستخدم crate للوصول إلى المحتوى بدءًا من جذر الكريت (المسار المطلق).^1.2.3 في ملف Cargo.toml؟^ إلى «تحديث التوافق» — وهو إصدار يسمح باستخدام >=1.2.3 و<2.0.0.lib.rs وmain.rs معًا؟📖 ملخص
modوحدة تعريف الكلمات المفتاحية؛ يمكن تضمينها بشكل متداخل (mod outer { mod inner { ... } }) أو تحميلها من ملف (mod xxx;)pubالتحكم في الرؤية: خاص بشكل افتراضي،pubعام،pub(crate)مرئي فقط داخل الصندوق،pub(super)مرئي فقط للوحدة النمطية الأمuseيبسط عمليات الاستدعاء من خلال إدخال المسارات؛ ويدعم نوعين من المسارات النسبية/المطلقة:super(الوحدة النمطية الأم) وcrate(الوحدة النمطية الجذرية)Cargo.tomlإدارة التبعيات باستخدام نظام الترقيم الدلالي (SemVer)؛ الفصل بين[dependencies]و[dev-dependencies]cargo build/test/doc/benchهي الأوامر الأساسية في Cargo، بينما تضمنcargo clippyوcargo fmtجودة الكود- مساحة العمل: تستخدم إدارة الحزم المتعددة إعداد
Cargo.tomlفي المستوى الأعلى؛ بينما يسرد[workspace]جميع الحزم الفرعية
📝 تمارين
- الصعوبة ⭐: قم بإنشاء برنامج يحتوي على وحدتين، هما
mathوgreeting. تحتوي الوحدةmathعلى دالة عامةadd(a: i32, b: i32) -> i32، بينما تحتوي الوحدةgreetingعلى دالة عامةsay_hello(name: &str) -> String. استدعِ هاتين الدالتين فيmain. - الصعوبة ⭐⭐: قم بمحاكاة نظام وحدات «المكتبة». أنشئ الوحدة
library، التي تتضمن الوحدة الفرعيةbooks(إدارة الكتب) والوحدة الفرعيةmembers(إدارة الأعضاء). تحتويbooksعلى الدالتينadd_bookوlist_books، وتحتويmembersعلى الدالتينadd_memberوlist_members. استخدمpub(super)وpub(crate)للتحكم في الرؤية بشكل مناسب. توضح الوحدةmainكيفية إضافة الكتب والأعضاء. - الصعوبة ⭐⭐⭐: استكشف بنية مشروع مساحة العمل «Cargo». أنشئ مشروع مساحة عمل محليًا يتضمن
core-lib(مكتبة توفر الدالتينaddوsubtract) وcli-app(ملف قابل للتنفيذ يقوم بإجراء الحسابات باستخدامcore-libوطباعة النتائج). قم بتكوين إعدادات مساحة العمل لـCargo.toml، وقم بتجميعها باستخدامcargo build --workspace، وقم بتشغيلها باستخدامcargo run -p cli-app.