Rust: الأنواع الرئيسية في المكتبة القياسية لـ Rust
آخر تحديث: 2026-08-26
توفر المكتبة القياسية لـ Rust (std) أنواعًا أساسية للتفاعل مع نظام التشغيل — قياس الوقت، ومتغيرات البيئة، وإدارة العمليات، وعمليات المسار. ومن خلال إتقان هذه الأنواع، ستتمكن برامجك المكتوبة بلغة Rust من التواصل بشكل حقيقي مع النظام.
إذا كانت لغة «Rust» نفسها هي «المحرك»، فإن المكتبة القياسية هي «عجلة القيادة ولوحة العدادات ونظام الملاحة». بدون المكتبة القياسية، لا يمكن لبرنامجك سوى إجراء العمليات الحسابية الأساسية (الجمع والطرح والضرب والقسمة؛ وتسلسل السلاسل). أما مع المكتبة القياسية، فيمكن لبرنامجك تحديد الوقت الحالي، وقراءة معلمات سطر الأوامر، وتنفيذ الأوامر الخارجية، والتعامل مع مسارات الملفات — ليصبح بذلك «تطبيقًا» حقيقيًّا.
1. ما ستتعلمه
std::time::Durationوstd::time::Instant— قياس الفواصل الزمنية وتوقيت البرامجstd::time::SystemTime—استرداد وقت نظام التشغيلstd::env::args—قراءة معلمات سطر الأوامرstd::env::var—قراءة متغيرات البيئة وتعيينهاstd::process::Command—تنفيذ أمر خارجي واسترداد الناتجstd::path::PathوPathBuf— عمليات المسار عبر الأنظمة الأساسية
2. قصة البرنامج النصي للنسخ الاحتياطي المجدول
(1) المعاناة: معاناة النسخ الاحتياطي اليدوي
توم هو مهندس عمليات يضطر إلى إجراء نسخ احتياطي يدوي للبيانات المهمة من الخوادم كل يوم قبل مغادرة العمل. وتشكل هذه العملية مصدر إزعاج حقيقي له:
- عليه تسجيل الدخول إلى الخادم وإدخال الأمر
tarيدويًّا - يجب أن تتضمن أسماء ملفات النسخ الاحتياطي التاريخ —
backup_20260703.tar.gz— فهو غالبًا ما يخطئ في كتابته. - يتم تخزين مسار النسخ الاحتياطي في متغير بيئي، لكنني أضطر إلى التحقق منه في كل مرة باستخدام
echo $BACKUP_PATH - إنه يرغب في كتابة برنامج نصي للتشغيل التلقائي، لكنه لا يعرف أبدًا منذ متى والبرنامج قيد التشغيل.
- تختلف فواصل المسارات باختلاف أنظمة التشغيل — حيث يستخدم نظام ويندوز
\، بينما يستخدم نظام لينكس/
«لو أمكنني كتابة برنامج بلغة Rust يسترد الوقت الحالي تلقائيًا، ويقرأ مسار النسخ الاحتياطي من متغيرات البيئة، وينفذ أمر الضغط، ويسجل وقت المعالجة... لكان ذلك مثاليًّا.»
(2) نهج مكتبة Rust القياسية
use std::time::{Instant, SystemTime, UNIX_EPOCH};
use std::env;
use std::process::Command;
fn main() {
let start = Instant::now();
println!("=== Scheduled Backup Script ===");
// 1. Get the current system time
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
println!("[Time] Currently Unix Timestamp: {}s", now);
// 2. Read Environment Variables
let backup_dir = env::var("BACKUP_DIR")
.unwrap_or_else(|_| String::from("./backup"));
let db_name = env::var("DB_NAME")
.unwrap_or_else(|_| String::from("my_database"));
println!("[Layout] Backup Directory: {}", backup_dir);
println!("[Layout] Database Name: {}", db_name);
// 3. Constructing Backup File Names
let archive_name = format!("{}/backup_{}.tar.gz", backup_dir, now);
// 4. Execute harmless external commands (Simulated Backup)
let output = Command::new("echo")
.arg(format!("Simulating backup of {} to {}", db_name, archive_name))
.output()
.expect("Command execution failed");
println!("[Execute] Command Output: {}", String::from_utf8_lossy(&output.stdout));
// 5. Computation time
let elapsed = start.elapsed();
println!("[Time taken] Operation time: {:?}", elapsed);
println!("=== Backup Complete ===");
}
يوضح هذا البرنامج النصي، الذي يقل طوله عن 30 سطراً، القدرات الأساسية لمكتبة Rust القياسية:
Instantقياس الوقت المنقضي،SystemTimeاسترداد وقت النظام،env::varقراءة متغيرات البيئة، وCommandتنفيذ الأوامر الخارجية. ويُعد كل نوع بمثابة «نافذة» للحصول على المعلومات من نظام التشغيل أو للتحكم فيه.
3. المفاهيم الأساسية
(1) أنظمة أنواع المفاتيح في المكتبة القياسية
graph TB
A[Rust Key Types in the Standard Library] --> B[Time-related]
A --> C[Environment-Related]
A --> D[Process-Related]
A --> E[Path-related]
B --> B1["Duration: Time Period"]
B --> B2["Instant: Instant Timing"]
B --> B3["SystemTime: System Clock"]
C --> C1["env::args(): Command-Line Arguments"]
C --> C2["env::var(): Environment Variables"]
C --> C3["env::set_var(): Set a variable"]
D --> D1["Command::new"]
D --> D2["status() / output()"]
D --> D3["stdin / stdout / stderr"]
E --> E1["Path: Immutable Path Slices"]
E --> E2["PathBuf: Paths to Growth"]
E --> E3["join / parent / exists"]
(2) مقارنة بين أنواع المفاتيح
| النوع/الوظيفة | الوحدة | الغرض | الطرق الرئيسية |
|---|---|---|---|
Duration |
std::time |
الفاصل الزمني (على سبيل المثال، 5 ثوانٍ، 100 مللي ثانية) | from_secs، from_millis، as_secs |
Instant |
std::time |
مؤقت أحادي الاتجاه منذ بدء تشغيل البرنامج | now، elapsed، duration_since |
SystemTime |
std::time |
وقت ساعة النظام (يمكن ضبطه عبر NTP) | now، duration_since، UNIX_EPOCH |
env::args |
std::env |
قراءة معلمات سطر الأوامر | إرجاع المكرر Args |
env::var |
std::env |
قراءة متغيرات البيئة | العودة إلى Result<String, VarError> |
Command std::process تنفيذ الأوامر الخارجية new، arg، output، status |
|||
PathBuf |
std::path |
مسار ملف قابل للتخصيص | push، pop، set_extension |
| مرجع مسار ثابت |
(3) العلاقة بين Path و PathBuf
Path |
PathBuf |
|
|---|---|---|
| الأنواع الشبيهة بالسلاسل | &str (مرجع غير قابل للتغيير) |
String (ملكية) |
| القابلية للتغيير | غير قابل للتغيير (عمليات للقراءة فقط) | قابل للتغيير (push، pop، إلخ) |
| موقع الذاكرة | مرجع في المكدس أو الكومة | مخزن مؤقت في الكومة |
| العمليات الشائعة | exists، is_dir، parent، join |
push، pop، set_extension |
| التحويل | path.to_path_buf() → PathBuf |
path_buf.as_path() → &Path |
(4) مرجع سريع لمقارنة أنواع الوقت
| النوع | الغرض | متزايد بشكل منتظم | الدقة | يمكن تعديله بواسطة النظام | الاستخدامات النموذجية |
|---|---|---|---|---|---|
Instant |
التوقيت داخل البرنامج | نعم | نانوثانية | لا | قياس وقت تنفيذ الكود |
SystemTime |
وقت ساعة النظام | لا | نانوثانية | نعم (NTP، إلخ) | الحصول على التاريخ والوقت الحاليين |
Duration |
الفترة الزمنية/الفاصل الزمني | غير متوفر | نانوثانية | غير متوفر | مهلة الانتظار، وضع السكون، العمليات الحسابية |
العلاقة بين
PathوPathBufمماثلة تمامًا لتلك الموجودة بين&strوString:PathBufهو مسار قابل للتغيير مع حق الملكية، وPathهو شريحة مسار مستعارة وغير قابلة للتغيير. يتم تعريف جميع عمليات المسار (join،parent، إلخ) علىPath.
4. أمثلة على أنواع المفاتيح في المكتبة القياسية
(1) ▶ المثال:قياس الزمن — المدة، اللحظة، وSystemTime (مستوى الصعوبة ⭐)
// ============================================
// Demo: The Three Time Types in the std::time Module
// Simulation: Program Timer and System Clock
// ============================================
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
fn main() {
println!("=== Time Type Demonstration ===\n");
// --- 1. Duration: Time Period ---
let five_secs = Duration::from_secs(5);
let hundred_ms = Duration::from_millis(100);
let two_mins = Duration::from_secs(2 * 60);
println!("[Duration] 5 seconds = {:?}", five_secs);
println!("[Duration] 100ms = {:?}", hundred_ms);
println!("[Duration] 2 minutes = {:?}", two_mins);
// Duration Operations: Addition, Subtraction, and Comparison
let total = five_secs + hundred_ms;
println!("[Duration] 5 seconds+100ms = {:?}", total);
println!("[Duration] 5 seconds > 100ms = {}", five_secs > hundred_ms);
// --- 2. Instant: Program Timer ---
let start = Instant::now();
// Simulate some time-consuming operations
let mut sum: u64 = 0;
for i in 0..1_000_000 {
sum = sum.wrapping_add(i);
}
let elapsed = start.elapsed();
println!("\n[Instant] Calculation sum={} Time taken: {:?}", sum, elapsed);
println!("[Instant] Takes milliseconds: {}ms", elapsed.as_millis());
println!("[Instant] Takes microseconds: {}µs", elapsed.as_micros());
// --- 3. SystemTime: System Time ---
let now = SystemTime::now();
let since_epoch = now.duration_since(UNIX_EPOCH).unwrap();
println!("\n[SystemTime] Current timestamp: {} seconds", since_epoch.as_secs());
println!("[SystemTime] Current timestamp: {} milliseconds", since_epoch.as_millis());
// Calculate the time one day ago
let one_day_ago = now - Duration::from_secs(24 * 60 * 60);
let since_epoch_ago = one_day_ago.duration_since(UNIX_EPOCH).unwrap();
println!("[SystemTime] Timestamp from one day ago: {} seconds", since_epoch_ago.as_secs());
println!("\n=== The time demonstration has ended ===");
}
الناتج:
=== Time Type Demonstration ===
[Duration] 5 seconds = 5s
[Duration] 100ms = 100ms
[Duration] 2 minutes = 120s
[Duration] 5 seconds+100ms = 5.1s
[Duration] 5 seconds > 100ms = true
[Instant] Calculation sum=499999500000 Time taken: 2.345ms
[Instant] Takes milliseconds: 2ms
[Instant] Takes microseconds: 2345µs
[SystemTime] Current timestamp: 1783012250 seconds
[SystemTime] Current timestamp: 1783012250123 milliseconds
[SystemTime] Timestamp from one day ago: 1782925850 seconds
=== The time demonstration has ended ===
Durationيمثل فترة زمنية (مثل «5 ثوانٍ») ويدعم عمليات الجمع والطرح والمقارنة.Instantهو «مؤقت أحادي الاتجاه منذ بدء تشغيل البرنامج» — وهو مناسب لقياس وقت تنفيذ الكود، ولا يتأثر بتعديلات وقت النظام.SystemTimeيقرأ ساعة النظام (التي يمكن ضبطها بواسطة NTP) وهو مناسب للحصول على التاريخ والوقت الحاليين.duration_since(UNIX_EPOCH)يسترد الطابع الزمني لنظام Unix.
(2) ▶ المثال:البيئة ووسائط سطر الأوامر — env::args و env::var (مستوى الصعوبة ⭐⭐)
// ============================================
// Demo: std::env Module for reading command-line arguments and environment variables
// Simulation: A configurable backup tool
// ============================================
use std::env;
fn main() {
println!("=== Environment and Parameter Explorer ===\n");
// --- 1. Reading Command-Line Arguments ---
let args: Vec<String> = env::args().collect();
println!("[args] Number of command-line arguments: {}", args.len());
if args.len() > 1 {
println!("[args] Program Name: {}", args[0]);
println!("[args] Input Parameters:");
for (i, arg) in args.iter().enumerate().skip(1) {
println!(" args[{}] = {}", i, arg);
}
} else {
println!("[args] No additional parameters were passed");
println!("[args] Presentation: The operating procedure is as follows");
println!(" cargo run -- --mode=backup --target=./data");
}
// --- 2. Read Environment Variables ---
println!("\n--- Environment Variable Detection ---");
// Try reading a few common environment variables
check_env_var("PATH");
check_env_var("HOME");
check_env_var("USER");
check_env_var("BACKUP_DIR"); // It may not exist.
check_env_var("DB_CONNECTION"); // It may not exist.
// --- 3. Read and Parse Custom Configuration ---
println!("\n--- Layout Analysis ---");
// Set an environment variable for demonstration purposes (Valid only within the current process)
// Note: Use set_var with caution in actual projects, it will affect the current process
env::set_var("MY_APP_MODE", "backup");
env::set_var("MY_APP_VERBOSE", "true");
let mode = env::var("MY_APP_MODE").unwrap_or_else(|_| "default".to_string());
let verbose = env::var("MY_APP_VERBOSE")
.map(|v| v == "true" || v == "1")
.unwrap_or(false);
println!("[Layout] Operating Mode: {}", mode);
println!("[Layout] Detailed Output: {}", verbose);
// --- 4. Iterate through all environment variables (Show only the first few) ---
println!("\n--- List of Environment Variables(first 5)---");
for (i, (key, value)) in env::vars().enumerate().take(5) {
println!(" {} = {}", key, value);
}
println!("\n=== Survey Complete ===");
}
/// Try reading the environment variables and printing them
fn check_env_var(name: &str) {
match env::var(name) {
Ok(val) => println!("[env] {} = {}", name, val),
Err(env::VarError::NotPresent) => println!("[env] {} = (Not set)", name),
Err(env::VarError::NotUnicode(_)) => println!("[env] {} = (non-UTF-8 value)", name),
}
}
الناتج:
=== Environment and Parameter Explorer ===
[args] Number of command-line arguments: 1
[args] No additional parameters were passed
[args] Presentation: The operating procedure is as follows
cargo run -- --mode=backup --target=./data
--- Environment Variable Detection ---
[env] PATH = C:\Windows\system32;C:\Windows;...
[env] HOME = (Not set)
[env] USER = (Not set)
[env] BACKUP_DIR = (Not set)
[env] DB_CONNECTION = (Not set)
--- Layout Analysis ---
[Layout] Operating Mode: backup
[Layout] Detailed Output: true
--- List of Environment Variables(first 5)---
ALLUSERSPROFILE = C:\ProgramData
APPDATA = C:\Users\Administrator\AppData\Roaming
...
=== Survey Complete ===
env::args()تُرجع مُكررًا لوسائط سطر الأوامر؛ حيث يمثل العنصر الأول مسار البرنامج.env::var(name)تقرأ متغير بيئة وتُرجعResult<String, VarError>— وقد تفشل هذه العملية إذا كان المتغير غير موجود (NotPresent) أو إذا كانت القيمة غير صالحة وفقًا لمعايير يونيكود (NotUnicode).env::set_varيضبط متغير بيئة (صالح فقط للعملية الحالية).env::vars()يتكرر عبر جميع متغيرات البيئة.
(3) ▶ المثال:الأوامر والمسارات — تنفيذ الأوامر الخارجية وعمليات المسارات (مستوى الصعوبة ⭐⭐)
// ============================================
// Demo: std::process::Command and std::path::Path/PathBuf
// Simulation:Backup Script——Build Path、Execute the compression command
// ============================================
use std::path::{Path, PathBuf};
use std::process::Command;
fn main() {
println!("=== Demonstration of Path Operations and External Commands ===\n");
// --- 1. Path and PathBuf Basic Operations ---
println!("--- Path Operations ---");
// Create PathBuf (Variable Paths with Ownership)
let mut backup_dir = PathBuf::new();
backup_dir.push("data");
backup_dir.push("backups");
println!("[PathBuf] Initial Path: {}", backup_dir.display());
// Set File Extensions
let mut archive = backup_dir.clone();
archive.push("database");
archive.set_extension("tar.gz");
println!("[PathBuf] Archived Files: {}", archive.display());
// Path Read-only operations
let path = Path::new("C:/Users/Alice/Documents/report.pdf");
println!("\n[Path] File Path: {}", path.display());
println!("[Path] File Name: {:?}", path.file_name());
println!("[Path] File extension: {:?}", path.extension());
println!("[Path] Parent directory: {:?}", path.parent());
println!("[Path] Does it exist?: {}", path.exists());
// Path Concatenation
let docs = Path::new("./docs");
let full_path = docs.join("rust").join("guide.md");
println!("[Path] Path Concatenation: {}", full_path.display());
// --- 2. Usage Command Execute an external command ---
println!("\n--- Executing External Commands ---");
// Example A: Execute "echo" Command (Harmless Command)
let echo_result = Command::new("echo")
.arg("Hello from Rust! Backup process started.")
.output()
.expect("echo Command execution failed");
println!("[Command] echo Output: {}",
String::from_utf8_lossy(&echo_result.stdout));
// Example B: Execute "whoami" Command (Show Current User)
let whoami_output = Command::new("whoami")
.output()
.expect("whoami Command execution failed");
if whoami_output.status.success() {
let username = String::from_utf8_lossy(&whoami_output.stdout);
println!("[Command] Current User: {}", username.trim());
} else {
let err = String::from_utf8_lossy(&whoami_output.stderr);
println!("[Command] whoami Failure: {}", err);
}
// Example C: Check whether the command was successful (status Pattern)
let status = Command::new("cmd")
.args(["/C", "dir", "./"])
.status()
.expect("dir Command execution failed");
if status.success() {
println!("[Command] dir The command was executed successfully (exit code: {})", status.code().unwrap_or(-1));
} else {
println!("[Command] dir Command execution failed (exit code: {:?})", status.code());
}
// --- 3. Combined Use: Build Command Based on Path ---
println!("\n--- Simulate the Backup Process ---");
let source = Path::new("./data/documents");
let dest = Path::new("./backup/documents_backup.tar.gz");
println!("Backup Source: {}", source.display());
println!("Backup Destination: {}", dest.display());
// Simulation tar Command (This will not actually be executed, just demonstrating command construction)
let _mock_cmd = Command::new("tar")
.arg("-czf")
.arg(dest)
.arg(source)
.status();
// Actually executing a harmless display command
let show_cmd = Command::new("echo")
.arg(format!(
"Would execute: tar -czf {} {}",
dest.display(),
source.display()
))
.output()
.unwrap();
println!("Simulation Commands: {}",
String::from_utf8_lossy(&show_cmd.stdout).trim());
println!("\n=== End of Presentation ===");
}
الناتج:
=== Demonstration of Path Operations and External Commands ===
--- Path Operations ---
[PathBuf] Initial Path: data\backups
[PathBuf] Archived Files: data\backups\database.tar.gz
[Path] File Path: C:/Users/Alice/Documents/report.pdf
[Path] File Name: Some("report.pdf")
[Path] File extension: Some("pdf")
[Path] Parent directory: Some("C:/Users/Alice/Documents")
[Path] Does it exist?: false
[Path] Path Concatenation: docs\rust\guide.md
--- Executing External Commands ---
[Command] echo Output: Hello from Rust! Backup process started.
[Command] Current User: DESKTOP-ABC123\Administrator
[Command] dir The command was executed successfully (exit code: 0)
--- Simulate the Backup Process ---
Backup Source: ./data/documents
Backup Destination: ./backup/documents_backup.tar.gz
Simulation Commands: Would execute: tar -czf ./backup/documents_backup.tar.gz ./data/documents
=== End of Presentation ===
Command::new("program name")ينشئ أمرًا جديدًا؛ وتُضاف المعلمات باستخدامargوargs.output()يلتقط مخرجات stdout وstderr (مناسب للحالات التي تتطلب معالجة المخرجات)، بينماstatus()يتحقق من رمز الخروج فقط (مناسب للحالات التي لا تكون فيها المخرجات مطلوبة).Path::display()يعرض المسارات بطريقة متوافقة مع جميع الأنظمة الأساسية.PathBufهو نسخة قابلة للتعديل منPathتدعم عمليات التعديل مثلpushوpopوset_extension.path.join(...)يُرجعPathBufجديدًا.
(4) ▶ المثال:تمرين شامل — أداة CLI: عارض معلومات الملفات (مستوى الصعوبة ⭐⭐⭐)
// ============================================
// Comprehensive Example: std::fs + std::path + std::time
// ============================================
use std::env;
use std::fs;
use std::path::Path;
use std::time::SystemTime;
fn format_size(size: u64) -> String {
const KB: u64 = 1024;
const MB: u64 = 1024 * KB;
const GB: u64 = 1024 * MB;
if size >= GB { format!("{:.2} GB", size as f64 / GB as f64) }
else if size >= MB { format!("{:.2} MB", size as f64 / MB as f64) }
else if size >= KB { format!("{:.2} KB", size as f64 / KB as f64) }
else { format!("{} B", size) }
}
fn format_time(systime: SystemTime) -> String {
let duration = systime.duration_since(SystemTime::UNIX_EPOCH).unwrap_or_default();
let secs = duration.as_secs();
let days = secs / 86400;
let hours = (secs % 86400) / 3600;
let minutes = (secs % 3600) / 60;
format!("{} days {:02}:{:02} UTC", days, hours, minutes)
}
fn inspect_file(path_str: &str) -> Result<(), Box<dyn std::error::Error>> {
let path = Path::new(path_str);
if !path.exists() {
println!("The path does not exist: {}", path.display());
return Ok(());
}
println!("=== File Information ===");
println!("Path: {}", path.display());
println!("File Name: {:?}", path.file_name());
println!("File extension: {:?}", path.extension());
println!("Parent directory: {:?}", path.parent());
if path.is_file() {
let metadata = fs::metadata(path)?;
println!("Size: {}", format_size(metadata.len()));
println!("Read-only: {}", metadata.permissions().readonly());
println!("Last Modified: {}", format_time(metadata.modified()?));
} else if path.is_dir() {
println!("Type: Table of Contents");
let entries: Vec<_> = fs::read_dir(path)?
.filter_map(|e| e.ok())
.collect();
println!("Number of entries: {}", entries.len());
for entry in entries.iter().take(10) {
let name = entry.file_name().to_string_lossy().to_string();
let tag = if entry.path().is_dir() { "DIR" } else { "FILE" };
println!(" [{}] {}", tag, name);
}
if entries.len() > 10 {
println!(" ... And also {} entries", entries.len() - 10);
}
}
Ok(())
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args: Vec<String> = env::args().collect();
let target = if args.len() > 1 { &args[1] } else { "." };
inspect_file(target)
}
الناتج (تشغيل cargo run -- src/main.rs):
=== File Information ===
Path: src/main.rs
File Name: Some("main.rs")
File extension: Some("rs")
Parent directory: Some("src")
Size: 1.23 KB
Read-only: false
Last Modified: 20504 days 08:30 UTC
يجمع هذا المثال بين استخدام
std::fs(بيانات تعريف الملف)، وstd::path(معالجة المسار)، وstd::time(تنسيق الوقت)، وstd::env(معلمات سطر الأوامر). يعرضformat_sizeحجم الملف بتنسيق سهل الاستخدام، ويقومformat_timeبتحويلSystemTimeإلى تنسيق زمني قابل للقراءة.
(5) ▶ المثال:تمرين شامل — مؤقت بسيط ومعلومات النظام (مستوى الصعوبة ⭐⭐)
// ============================================
// Comprehensive Example: std::time + std::env + std::process
// ============================================
use std::env;
use std::process::Command;
use std::time::{Duration, Instant};
struct Timer {
start: Instant,
label: String,
}
impl Timer {
fn new(label: &str) -> Self {
println!("[{}] The timer starts", label);
Timer { start: Instant::now(), label: label.to_string() }
}
fn elapsed(&self) -> Duration {
self.start.elapsed()
}
fn stop(self) -> Duration {
let elapsed = self.elapsed();
println!("[{}] Time's up: {:.3}s", self.label, elapsed.as_secs_f64());
elapsed
}
}
fn main() {
println!("=== System Information ===");
println!("Current Directory: {:?}", env::current_dir().unwrap_or_default());
println!("Operating System: {}", env::consts::OS);
println!("Architecture: {}", env::consts::ARCH);
println!("\n=== Environment Variables ===");
for key in &["HOME", "PATH", "USER", "LANG"] {
match env::var(key) {
Ok(val) => println!("{}: {} Character", key, val.len()),
Err(_) => println!("{}: (Not set)", key),
}
}
println!("\n=== Timed Demonstration ===");
let t1 = Timer::new("Calculating the Fibonacci Sequence");
let mut fib: Vec<u64> = vec![0, 1];
for _ in 0..45 {
let next = fib[fib.len()-1] + fib[fib.len()-2];
fib.push(next);
}
t1.stop();
println!("fib(45) = {}", fib[45]);
let t2 = Timer::new("String Operations");
let mut s = String::new();
for i in 0..10_000 {
s.push_str(&format!("item{} ", i));
}
let len = s.len();
t2.stop();
println!("String Length: {} Character", len);
println!("\n=== Process Exit Code ===");
let status = Command::new("cmd")
.args(&["/C", "echo", "hello"])
.status();
match status {
Ok(s) => println!("Exit Code: {}", s.code().unwrap_or(-1)),
Err(e) => println!("Execution Failed: {}", e),
}
}
الناتج:
=== System Information ===
Current Directory: "G:\\..."
Operating System: windows
Architecture: x86_64
=== Environment Variables ===
HOME: 20 Character
PATH: 500 Character
...
=== Timed Demonstration ===
[Calculating the Fibonacci Sequence] The timer starts
[Calculating the Fibonacci Sequence] Time's up: X.XXXs
fib(45) = 1134903170
[String Operations] The timer starts
[String Operations] Time's up: X.XXXs
String Length: 88889 Character
=== Process Exit Code ===
Exit Code: 0
Timerيتتبع الوقت تلقائيًا باستخدام نمط RAII الخاص بـInstant؛env::constsيسترد معلومات النظام الأساسي؛env::varيقرأ متغيرات البيئة؛Commandينفذ الأوامر الخارجية ويسترد رمز الخروج.
❓ أسئلة شائعة
Instant وSystemTime؟ ومتى ينبغي استخدام كل منهما؟Instant هو مؤقت يتزايد بشكل منتظم، بينما SystemTime يقرأ ساعة النظام.env::var وenv::args؟String.Command::output() وCommand::status()؟output() يلتقط مخرجات stdout وstderr، بينما status() يتحقق فقط من رمز الخروج.Path و PathBuf هما طريقتان متعددتا المنصات وتستخدمان داخليًّا فواصل المسارات الخاصة بكل منصة.Command، هل يتم البحث تلقائيًا في متغير البيئة PATH؟Command::new("program name") بالبحث في متغير البيئة PATH.📖 ملخص
Durationيمثل فترة زمنية (بالثواني، الميلي ثانية، الميكروثانية) ويدعم عمليات الجمع والطرح والمقارنة؛Instantهو مؤقت أحادي الاتجاه، مناسب لقياس الوقت المنقضي؛SystemTimeيقرأ ساعة النظام وهو مناسب للحصول على الطوابع الزمنيةenv::args()تُرجع مُكررًا لوسائط سطر الأوامر؛ العنصر الأول هو مسار البرنامج؛env::var(name)تقرأ متغيرات البيئة وتُرجعResult<String, VarError>env::set_varتعيين متغير بيئة (يسري فقط على العملية الحالية)؛ استخدمه بحذر في بيئة الإنتاج؛env::vars()تكرار جميع متغيرات البيئةCommand::newتنفيذ أمر خارجي؛arg/argsإضافة معلمات؛output()التقاط الناتج؛status()التحقق من رمز الخروجPathBufهو مسار متغير ذو ملكية (على غرارString) يدعم التعديلات مثلpushوpopوset_extension، وهكذا دواليك.Pathهو شريحة مسار مستعارة غير قابلة للتغيير (على غرار&str) تدعم العمليات المخصصة للقراءة فقط مثلexistsوparentوjoinوfile_name.
📝 تمارين
- الصعوبة ⭐: اكتب برنامجًا يستخدم
Instantلقياس وقت تنفيذ حلقة (العد من 1 إلى 1,000,000) ويطبع الوقت المنقضي بالميلي ثانية (ms) والميكرو ثانية (µs) على التوالي. كما يجب استخدامSystemTimeلاسترداد الطابع الزمني لنظام Unix عند بدء تشغيل البرنامج وعرضه. - الصعوبة ⭐⭐: قم بتنفيذ «عارض متغيرات البيئة». يجب أن يقوم البرنامج بقراءة قيمة متغير بيئة محدد عبر وسيطة سطر الأوامر وعرضها. إذا كان المتغير غير موجود، فاعرض رسالة توضيحية. ميزة إضافية: إذا لم يتم توفير أي وسيطة، فقم بإدراج جميع متغيرات البيئة التي تبدأ بـ
MY_أوRUST_مع قيمها. - الصعوبة ⭐⭐⭐: قم بتنفيذ «أداة نسخ احتياطي بسيطة». استخدم
PathBufلإنشاء الدليل المصدر ومسار الأرشيف الوجهة. اقرأ التكوين عبر متغيرات البيئةBACKUP_SOURCEوBACKUP_DEST(إذا لم يتم تعيينهما، فاستخدم القيم الافتراضية./dataو./backup/archive.tar.gz). استخدمCommandلتنفيذ الأمرechoلمحاكاة عملية النسخ الاحتياطي — اطبع «Backing up [source] to [dest]». استخدمInstantلتسجيل وطباعة إجمالي الوقت المنقضي في البداية والنهاية. يجب عليك استخدامexists()فيPathللتحقق من وجود الدليل المصدر.