Как преобразовать целое число (i32, u64 и т.д.) в строку String или &str в Rust?
Основные способы преобразования целого числа в строку в Rust
В Rust нельзя просто сложить строку и число оператором +, потому что это язык со строгой статической типизацией. Однако существует несколько идиоматичных способов преобразовать целое число (i32, u64, usize и т.д.) в строку. Рассмотрим их от самого простого к более продвинутому.
1. Макрос format! (рекомендуемый для новичков)
Это самый универсальный и читаемый способ. Он работает как println!, но возвращает String вместо вывода в консоль.
fn main() {
let number: i32 = 42;
let result = number * 2;
let message = format!("Результат: {}", result);
println!("{}", message); // Выведет: Результат: 84
}
Преимущества:
- Простота и читаемость
- Поддерживает форматирование (например,
{:b}для двоичного вывода) - Не требует импорта дополнительных трейтов
2. Метод to_string()
Метод to_string() доступен для любого типа, реализующего трейт Display. Все целочисленные типы в Rust реализуют этот трейт.
fn main() {
let number: i32 = 42;
let number_string = number.to_string();
// Теперь можно соединять с помощью метода push_str или через format!
let mut message = String::from("Результат: ");
message.push_str(&number_string);
println!("{}", message); // Выведет: Результат: 42
}
Важно: to_string() возвращает String, а не &str. Если вам нужен &str, используйте &number_string (заимствование).
3. Метод into() (через трейт Into)
Этот метод работает, если тип назначения (в данном случае String) реализует From для исходного типа. Для целых чисел это работает, но менее читаемо.
fn main() {
let number: i32 = 42;
let number_string: String = number.into();
println!("Число: {}", number_string);
}
Обратите внимание: into() требует явного указания типа переменной, иначе компилятор не сможет вывести его. Это может быть неудобно.
4. Преобразование в &str — напрямую невозможно
В Rust нельзя преобразовать число напрямую в &str, потому что &str — это ссылка на строку, которая должна где-то храниться. Число не является строкой в памяти. Единственный способ получить &str — сначала создать String (через to_string() или format!), а потом взять ссылку на неё:
fn main() {
let number = 42;
let number_string = number.to_string(); // String
let number_str: &str = &number_string; // &str
println!("{}", number_str);
}
Рекомендации
- Для простого вывода — используйте
format!илиprintln!напрямую с плейсхолдером{}. - Если нужно сохранить строку — используйте
to_string(). - Избегайте
into()для преобразования чисел в строки — это менее читаемо и требует явной аннотации типа. - Запомните: числа нельзя превратить в
&strбез промежуточнойString.
В вашем примере самый простой и правильный способ — использовать format!:
fn main() {
let number: i32 = 42;
let result = number * 2;
let message = format!("Результат: {}", result);
println!("{}", message);
}
Это решит вашу проблему и является идиоматичным Rust-кодом.
<<Альтернативный подход: использование крейта itoa для максимальной производительности
Если вы пишете высоконагруженное приложение (например, парсер или сервер), где преобразование чисел в строки происходит миллионы раз, стандартные методы to_string() и format! могут быть медленными. В таких случаях стоит обратить внимание на крейт itoa.
Крейт itoa выполняет преобразование целых чисел в строки без выделения дополнительной памяти на куче (heap allocation), что значительно быстрее, чем to_string(), который создаёт новую String.
// Добавьте в Cargo.toml: itoa = "1.0"
use itoa;
fn main() {
let number: i32 = 42;
let mut buffer = itoa::Buffer::new();
let number_str: &str = buffer.format(number);
println!("Число: {}", number_str);
}
Как это работает:
itoa::Buffer— это фиксированный буфер на стеке (достаточно большой для любого целого числа).- Метод
format()записывает строковое представление числа в этот буфер и возвращает&str, ссылающийся на него. - Нет выделения памяти на куче, нет копирования — только запись в стек.
Когда использовать:
- В критически важных по производительности участках кода.
- Когда нужно избежать лишних аллокаций (например, в циклах).
Недостатки:
- Требуется добавить внешнюю зависимость в
Cargo.toml. - Не поддерживает форматирование (например, вывод в шестнадцатеричном виде). Для этого всё равно нужен
format!.
Для 99% случаев вам будет достаточно to_string() или format!. Но если вы оптимизируете производительность, запомните про itoa.