std::time: Работа с временем
2. std::process: Управление процессами и внешними командами
3. std::env: Доступ к окружению и аргументам
Практические советы
Пример: Комбинирование модулей
Упражнение
Заключение
В этом разделе мы разберём модули стандартной библиотеки Rust, связанные с обработкой времени и управлением процессами: std::time, std::process и std::env. Эти инструменты позволяют измерять время, запускать внешние команды и взаимодействовать с окружающей средой программы. Лекция подойдёт как новичкам, так и опытным разработчикам, желающим углубить знания. Мы рассмотрим каждый модуль с примерами, нюансами и практическими советами.
std::time: Работа с временемМодуль std::time предоставляет типы для работы с временем: Duration для интервалов, Instant для измерения прошедшего времени и SystemTime для работы с системными часами.
DurationDuration представляет промежуток времени с наносекундной точностью.
Пример: создание и использование Duration:
use std::time::Duration;
fn main() {
let duration = Duration::from_secs(5); // 5 секунд
println!("Секунды: {}", duration.as_secs()); // 5
println!("Наносекунды: {}", duration.as_nanos()); // 5_000_000_000
let extra = Duration::from_millis(500); // 500 миллисекунд
let total = duration + extra;
println!("Всего: {:.2} сек", total.as_secs_f64()); // 5.50 сек
}
Комментарии:
from_secs, from_millis — удобные конструкторы.as_secs_f64 возвращает длительность в секундах как f64.+, -).InstantInstant используется для измерения времени выполнения кода (монотонные часы).
Пример: замер времени:
use std::time::Instant;
use std::thread;
fn main() {
let start = Instant::now();
thread::sleep(Duration::from_secs(1));
let elapsed = start.elapsed();
println!("Прошло: {:.2} сек", elapsed.as_secs_f64()); // ~1.00 сек
}
Комментарии:
now фиксирует текущий момент.elapsed возвращает Duration от момента создания.SystemTimeSystemTime представляет момент времени относительно системных часов (может быть неточным из-за корректировок).
Пример: работа с датой:
use std::time::{SystemTime, UNIX_EPOCH};
fn main() -> std::io::Result<()> {
let now = SystemTime::now();
let since_epoch = now.duration_since(UNIX_EPOCH)?;
println!("Секунд с эпохи: {}", since_epoch.as_secs());
let earlier = UNIX_EPOCH + Duration::from_secs(1_000_000_000);
println!("Прошло с 2001-09-09? {}",
now.duration_since(earlier).unwrap().as_secs());
Ok(())
}
Комментарии:
duration_since возвращает Result, так как время может быть "в прошлом".UNIX_EPOCH — это 1 января 1970 года, 00:00 UTC.Предупреждение: SystemTime может быть неточным из-за изменений системных часов. Для замеров используйте Instant.
std::process: Управление процессами и внешними командамиМодуль std::process позволяет запускать внешние процессы, взаимодействовать с их вводом-выводом и получать код завершения.
Основные типы и функции:
Command: Построение команды.Output: Результат выполнения (stdout, stderr, код).exit: Завершение текущего процесса.Пример: запуск команды ls (или dir на Windows):
use std::process::Command;
fn main() -> std::io::Result<()> {
let output = if cfg!(target_os = "windows") {
Command::new("cmd").args(&["/C", "dir"]).output()?
} else {
Command::new("ls").arg("-l").output()?
};
println!("Статус: {}", output.status);
println!("Вывод: {}", String::from_utf8_lossy(&output.stdout));
if !output.stderr.is_empty() {
println!("Ошибки: {}", String::from_utf8_lossy(&output.stderr));
}
Ok(())
}
Комментарии:
cfg! обеспечивает кроссплатформенность.output() возвращает Output с полями status, stdout, stderr.from_utf8_lossy преобразует байты в строку, заменяя некорректные символы.std::env: Доступ к окружению и аргументамМодуль std::env предоставляет доступ к переменным окружения, аргументам командной строки и текущему каталогу.
Основные функции:
args: Аргументы командной строки.var: Получение переменной окружения.current_dir: Текущая рабочая директория.Пример: чтение аргументов и переменных:
use std::env;
fn main() -> std::io::Result<()> {
// Аргументы командной строки
let args: Vec = env::args().collect();
println!("Аргументы: {:?}", args);
// Переменная окружения
match env::var("PATH") {
Ok(path) => println!("PATH: {}", path),
Err(e) => println!("Ошибка PATH: {}", e),
}
// Текущая директория
let dir = env::current_dir()?;
println!("Текущая директория: {:?}", dir);
Ok(())
}
Комментарии:
args() возвращает итератор, первый элемент — путь к программе.var возвращает Result, так как переменная может отсутствовать.current_dir возвращает PathBuf.Заметка: Используйте env::args_os вместо args, если нужны сырые строки ОС (например, для некорректного UTF-8).
std::time: Используйте Instant для замеров производительности, а SystemTime — для работы с календарным временем.std::process: Проверяйте status.success(), чтобы убедиться в успешном выполнении команды.std::env: Обрабатывайте отсутствие переменных с помощью unwrap_or для значений по умолчанию.Программа, измеряющая время выполнения команды:
use std::env;
use std::process::Command;
use std::time::Instant;
fn main() -> std::io::Result<()> {
let args: Vec = env::args().collect();
if args.len() < 2 {
println!("Укажите команду, например: cargo run -- ls");
return Ok(());
}
let cmd = &args[1];
let start = Instant::now();
let output = Command::new(cmd).output()?;
let elapsed = start.elapsed();
println!("Статус: {}", output.status);
println!("Время выполнения: {:.2} сек", elapsed.as_secs_f64());
println!("Вывод: {}", String::from_utf8_lossy(&output.stdout));
Ok(())
}
Этот пример использует env для аргументов, process для запуска команды и time для замера времени.
Напишите программу, которая:
std::env::args.std::process::Command.Instant.Result.Подсказка: Используйте take для ограничения вывода.
Модули std::time, std::process и std::env предоставляют всё необходимое для работы с временем, процессами и окружением. Они просты в использовании, но требуют внимания к обработке ошибок и кроссплатформенности. Освоив их, вы сможете создавать утилиты, скрипты и приложения с внешними зависимостями. Далее мы рассмотрим сетевые возможности.
Выполните упражнение или двигайтесь дальше!