std::fmt
2. Пример работы с std::collections
и std::fs
Заключение
В этом разделе мы рассмотрим практические примеры использования стандартной библиотеки Rust. Мы сосредоточимся на двух ключевых аспектах:
std::fmt
std::collections
и std::fs
std::fmt
Модуль std::fmt
позволяет настроить форматирование вывода для пользовательских типов данных. Рассмотрим пример с реализацией трейтов Display
и Debug
.
use std::fmt;
// Определяем структуру
struct Person {
name: String,
age: u32,
}
// Реализация трейта Debug (автоматически через derive или вручную)
#[derive(Debug)] // Автоматическая реализация для отладки
struct PersonAutoDebug {
name: String,
age: u32,
}
// Ручная реализация Display
impl fmt::Display for Person {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// Форматируем строку как "Имя: <name>, Возраст: <age>"
write!(f, "Имя: {}, Возраст: {}", self.name, self.age)
}
}
fn main() {
let person = Person {
name: String::from("Алексей"),
age: 30,
};
let person_auto = PersonAutoDebug {
name: String::from("Мария"),
age: 25,
};
// Вывод с Display
println!("{}", person); // Имя: Алексей, Возраст: 30
// Вывод с Debug (автоматический)
println!("{:?}", person_auto); // PersonAutoDebug { name: "Мария", age: 25 }
}
Объяснение:
#[derive(Debug)]
: Автоматически реализует трейт Debug
для отладочного вывода.impl fmt::Display
: Ручная реализация для пользовательского формата вывода.write!
: Макрос для записи форматированной строки в Formatter
.Практический совет: Используйте Debug
для отладки, а Display
для вывода, предназначенного для пользователей.
std::collections
и std::fs
Теперь рассмотрим пример, объединяющий работу с коллекциями (HashMap
) и файловой системой (std::fs
).
use std::collections::HashMap;
use std::fs;
use std::io;
fn main() -> io::Result<()> {
// Читаем файл
let content = fs::read_to_string("input.txt")
.unwrap_or_else(|_| String::from("Файл не найден, начнём с пустого текста"));
// Подсчитываем слова
let mut word_count: HashMap<String, u32> = HashMap::new();
for word in content.split_whitespace() {
*word_count.entry(word.to_string()).or_insert(0) += 1;
}
// Формируем результат
let mut output = String::new();
for (word, count) in &word_count {
output.push_str(&format!("Слово: {}, Частота: {}\n", word, count));
}
// Записываем в файл
fs::write("output.txt", &output)?;
println!("Результат записан в output.txt");
Ok(())
}
Объяснение:
fs::read_to_string
: Читает содержимое файла в строку.HashMap::entry
: Эффективно добавляет или обновляет записи в хэш-таблице.fs::write
: Записывает данные в файл, создавая его при необходимости.Пример ввода (input.txt):
Rust Rust Python Rust Java
Вывод (output.txt):
Слово: Rust, Частота: 3
Слово: Python, Частота: 1
Слово: Java, Частота: 1
Практический совет: Для больших файлов используйте BufReader
вместо read_to_string
для повышения производительности.
В этом разделе мы изучили, как использовать std::fmt
для кастомного вывода, std::collections
для работы с данными и std::fs
для операций с файлами. Эти инструменты являются основой для большинства программ на Rust.