Rust: Key Types in the Rust Standard Library
Last updated: 2026-08-26
The Rust standard library (std) provides core types for interacting with the operating system—time measurement, environment variables, process management, and path operations. By mastering these types, your Rust programs will be able to truly communicate with the system.
If the Rust language itself is the "engine," then the standard library is the "steering wheel, dashboard, and navigation system." Without the standard library, your program can only perform basic calculations (addition, subtraction, multiplication, and division; string concatenation). With the standard library, your program can determine the current time, read command-line arguments, execute external commands, and manipulate file paths—thus becoming a true "application."
1. What You'll Learn
std::time::Durationandstd::time::Instant—Time Interval Measurement and Program Timingstd::time::SystemTime—Retrieving the operating system timestd::env::args—Read command-line argumentsstd::env::var—Reading and Setting Environment Variablesstd::process::Command—Execute an external command and retrieve the outputstd::path::PathandPathBuf—Cross-Platform Path Operations
2. The Story of the Scheduled Backup Script
(1) The Pain: The Pain of Manual Backups
Tom is an operations engineer who has to manually back up important data from the servers every day before leaving work. This process is a real headache for him:
- He has to log in to the server and manually type the
tarcommand - The backup file names should include the date—
backup_20260703.tar.gz—he often types it wrong. - The backup path is stored in an environment variable, but I have to check it every time using
echo $BACKUP_PATH - He wants to write an automation script, but he never knows how long the program has been running.
- Path separators differ across operating systems—Windows uses
\, while Linux uses/
"If I could write a Rust program that automatically retrieves the current time, reads the backup path from the environment variables, executes the compression command, and logs the processing time... that would be perfect."
(2) The Rust Standard Library Approach
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 ===");
}
This script, which is less than 30 lines long, demonstrates the core capabilities of the Rust standard library:
Instantmeasuring elapsed time,SystemTimeretrieving the system time,env::varreading environment variables, andCommandexecuting external commands. Each type serves as a "window" for obtaining information from or controlling the operating system.
3. Core Concepts
(1) Key Type Systems in the Standard Library
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) Comparison of Key Types
| Type/Function | Module | Purpose | Key Methods |
|---|---|---|---|
Duration |
std::time |
Time interval (e.g., 5 seconds, 100 milliseconds) | from_secs, from_millis, as_secs |
Instant |
std::time |
Monotonic timer since program startup | now, elapsed, duration_since |
SystemTime |
std::time |
System clock time (can be adjusted by NTP) | now, duration_since, UNIX_EPOCH |
env::args |
std::env |
Read command-line arguments | Return the Args iterator |
env::var |
std::env |
Read Environment Variables | Back to Result<String, VarError> |
Command std::process Execute external commands new, arg, output, status |
|||
PathBuf |
std::path |
Customizable file path | push, pop, set_extension |
| Immutable path reference |
(3) The Relationship Between Path and PathBuf
Path |
PathBuf |
|
|---|---|---|
| String-like types | &str (immutable reference) |
String (ownership) |
| Mutability | Immutable (read-only operations) | Mutable (push, pop, etc.) |
| Memory Location | Reference on the stack or heap | Buffer on the heap |
| Common Operations | exists, is_dir, parent, join |
push, pop, set_extension |
| Conversion | path.to_path_buf() → PathBuf |
path_buf.as_path() → &Path |
(4) Quick Reference for Comparing Time Types
| Type | Purpose | Monotonically Increasing | Precision | Can Be Adjusted by the System | Typical Uses |
|---|---|---|---|---|---|
Instant |
In-program timing | Yes | Nanoseconds | No | Measure code execution time |
SystemTime |
System clock time | No | Nanoseconds | Yes (NTP, etc.) | Get current date and time |
Duration |
Time Period/Interval | N/A | Nanoseconds | N/A | Timeout, Sleep, Arithmetic Operations |
The relationship between
PathandPathBufis exactly analogous to that between&strandString:PathBufis a mutable path with ownership, andPathis a borrowed, immutable path slice. All path operations (join,parent, etc.) are defined onPath.
4. Examples of Key Types in the Standard Library
▶ Example 1: Time Measurement—Duration, Instant, and SystemTime (Difficulty ⭐)
Output:
=== Time Type Demonstration ===
[Duration] 5 seconds = <five_secs>
[Duration] 100ms = <hundred_ms>
[Duration] 2 minutes = <two_mins>
[Duration] 5 seconds+100ms = <total>
[Duration] 5 seconds > 100ms = <five_secs > hundred_ms>
[Instant] Calculation sum=<elapsed> Time taken: 0
[Instant] Takes milliseconds: <elapsed.as_millis()>ms
[Instant] Takes microseconds: <elapsed.as_micros()>µs
[SystemTime] Current timestamp: <since_epoch.as_secs()> seconds
[SystemTime] Current timestamp: <since_epoch.as_millis()> milliseconds
[SystemTime] Timestamp from one day ago: <since_epoch_ago.as_secs()> seconds
// ============================================
// 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 ===");
}
Output:
=== 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 ===
Durationrepresents a time interval (e.g., "5 seconds") and supports addition, subtraction, and comparison operations.Instantis a "monotonic timer since program startup"—suitable for measuring code execution time, unaffected by system time adjustments.SystemTimereads the system clock (which can be adjusted by NTP) and is suitable for obtaining the current date and time.duration_since(UNIX_EPOCH)retrieves the Unix timestamp.
▶ Example 2: Environment and Command-Line Arguments—env::args and env::var (Difficulty ⭐⭐)
Output:
=== Environment and Parameter Explorer ===
[args] Number of command-line arguments: <args.len()>
[args] Program Name: <args[0]>
[args] Input Parameters:
args[<i>] = <arg>
[args] No additional parameters were passed
[args] Presentation: The operating procedure is as follows
cargo run -- --mode=backup --target=./data
--- Environment Variable Detection ---
--- Layout Analysis ---
[Layout] Operating Mode: <mode>
[Layout] Detailed Output: <verbose>
--- List of Environment Variables(first 5)---
<key> = <value>
=== Survey Complete ===
[env] <name> = <val>
[env] <name> = (Not set)
[env] <name> = (non-UTF-8 value)
// ============================================
// 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),
}
}
Output:
=== 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()Returns an iterator over command-line arguments; the first element is the program path.env::var(name)Reads an environment variable and returnsResult<String, VarError>—this may fail if the variable does not exist (NotPresent) or if the value is not valid Unicode (NotUnicode).env::set_varSets an environment variable (valid only for the current process).env::vars()Iterates through all environment variables.
▶ Example 3: Command and Path—Executing External Commands and Path Operations (Difficulty ⭐⭐)
Output:
=== Demonstration of Path Operations and External Commands ===
--- Path Operations ---
[PathBuf] Initial Path: <backup_dir.display()>
[PathBuf] Archived Files: <archive.display()>
[Path] File Path: <path.display()>
[Path] File Name: <path.file_name()>
[Path] File extension: <path.extension()>
[Path] Parent directory: <path.parent()>
[Path] Does it exist?: <path.exists()>
[Path] Path Concatenation: <full_path.display()>
--- Executing External Commands ---
[Command] echo Output: <String::from_utf8_lossy(&echo_result.stdout)>
[Command] Current User: <username.trim()>
[Command] whoami Failure: <err>
[Command] dir The command was executed successfully (exit code: <status.code().unwrap_or(-1)>)
[Command] dir Command execution failed (exit code: <status.code()>)
--- Simulate the Backup Process ---
Backup Source: <source.display()>
Backup Destination: <dest.display()>
Simulation Commands: <String::from_utf8_lossy(&show_cmd.stdout).trim()>
// ============================================
// 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 ===");
}
Output:
=== 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")creates a new command; parameters are added usingargandargs.output()captures stdout and stderr (suitable for scenarios requiring output processing), whilestatus()checks only the exit code (suitable for scenarios where output is not needed).Path::display()displays paths in a cross-platform manner.PathBufis a mutable version ofPaththat supports modification operations such aspush,pop, andset_extension.path.join(...)returns a newPathBuf.
▶ Example 4: Comprehensive Exercise—CLI Tool: File Information Viewer (Difficulty ⭐⭐⭐)
Output:
The path does not exist: <path.display()>
=== File Information ===
Path: <path.display()>
File Name: <path.file_name()>
File extension: <path.extension()>
Parent directory: <path.parent()>
Size: <format_size(metadata.len())>
Read-only: <metadata.permissions().readonly()>
Last Modified: <format_time(metadata.modified()?)>
Type: Table of Contents
Number of entries: <entries.len()>
[<tag>] <name>
... And also <entries.len() - 10> entries
// ============================================
// 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)
}
Output:
=== 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
This example combines the use of
std::fs(file metadata),std::path(path manipulation),std::time(time formatting), andstd::env(command-line arguments).format_sizedisplays the file size in a user-friendly format, andformat_timeconvertsSystemTimeinto a readable time format.
▶ Example 5: Comprehensive Exercise—Simple Timer and System Information (Difficulty ⭐⭐)
Output:
[<label>] The timer starts
[<elapsed.as_secs_f64()>] Time's up: <self.label>s
=== System Information ===
Current Directory: <env::current_dir().unwrap_or_default()>
Operating System: <env::consts::OS>
Architecture: <env::consts::ARCH>
=== Environment Variables ===
<key>: <val.len()> Character
<key>: (Not set)
=== Timed Demonstration ===
fib(45) = <fib[45]>
String Length: 0 Character
=== Process Exit Code ===
Exit Code: <s.code().unwrap_or(-1)>
Execution Failed: <e>
// ============================================
// 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),
}
}
Output:
=== 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
TimerAutomatically tracks time usingInstant's RAII pattern;env::constsretrieves platform information;env::varreads environment variables;Commandexecutes external commands and retrieves the exit code.
❓ FAQ
Instant and SystemTime? When should each be used?Instant is a monotonically increasing timer, while SystemTime reads the system clock.env::var and env::args?String.Command::output() and Command::status()?output() captures stdout and stderr, while status() only checks the exit code.Path and PathBuf are cross-platform and internally use platform-specific path separators.Command, is the PATH environment variable automatically searched?Command::new("program name") searches the PATH environment variable.📖 Summary
Durationrepresents a time interval (seconds, milliseconds, microseconds) and supports addition, subtraction, and comparison operations;Instantis a monotonic timer, suitable for measuring elapsed time;SystemTimereads the system clock and is suitable for obtaining timestampsenv::args()Returns an iterator of command-line arguments; the first element is the program path;env::var(name)Reads environment variables and returnsResult<String, VarError>env::set_varSet an environment variable (effective only for the current process); use with caution in production;env::vars()Iterate through all environment variablesCommand::newExecute an external command;arg/argsadd parameters;output()capture the output;status()check the exit codePathBufis a variable path with ownership (similar toString) that supports modifications such aspush,pop,set_extension, and so on.Pathis a borrowed immutable path slice (similar to&str) that supports read-only operations such asexists,parent,join, andfile_name.
📝 Exercises
- Difficulty ⭐: Write a program that uses
Instantto measure the execution time of a loop (counting from 1 to 1,000,000) and prints the elapsed time in milliseconds (ms) and microseconds (µs), respectively. Also, useSystemTimeto retrieve the Unix timestamp when the program starts and print it. - Difficulty ⭐⭐: Implement an "environment variable viewer." The program should read and print the value of an environment variable specified via a command-line argument. If the variable does not exist, print a friendly message. Additional feature: If no argument is provided, list all environment variables beginning with
MY_orRUST_along with their values. - Difficulty ⭐⭐⭐: Implement a "simple backup tool." Use
PathBufto construct the source directory and the destination archive path. Read the configuration via the environment variablesBACKUP_SOURCEandBACKUP_DEST(if not set, use the default values./dataand./backup/archive.tar.gz). UseCommandto execute theechocommand to simulate the backup process—print "Backing up [source] to [dest]". UseInstantto record and print the total elapsed time at the beginning and end. You must usePath'sexists()to check whether the source directory exists.