Avatar ·

Как преобразовать целое число (integer) в строку (String) в Rust?

Всем привет! Я только начал изучать Rust и столкнулся с проблемой: мне нужно преобразовать целое число в строку, чтобы вывести его или объединить с другими строками. В других языках (например, Python или JavaScript) это делается очень просто — str(42) или (42).toString(). Но в Rust я не могу найти прямого аналога. Вот мой код: ```rust fn main() { let number: i32 = 42; let message = "Ответ: " + number; // Ошибка! println!("{}", message); } ``` Компилятор выдаёт ошибку: `cannot add `i32` to `&str``. Я понимаю, что Rust строго типизирован, но как правильно преобразовать число в строку? Я пробовал использовать `number.to_string()`, но не уверен, что это лучший способ. Есть ли другие методы? И что делать, если нужно преобразовать число в `&str`, а не в `String`? Буду благодарен за подробное объяснение с примерами. Теги: строки, rust, преобразование-типов, целые-числа <<>>

Основной способ: метод to_string()

Самый простой и рекомендуемый способ преобразовать целое число в строку в Rust — использовать метод to_string(), который доступен для всех типов, реализующих трейт Display. Все целочисленные типы (i32, u64, i8, usize и т.д.) реализуют этот трейт, поэтому метод работает без дополнительных импортов.

fn main() {
    let number: i32 = 42;
    let message = format!("Ответ: {}", number); // Альтернатива: макрос format!
    let string_number = number.to_string(); // "42"
    println!("{}", string_number); // Вывод: 42
    
    // Объединение строк
    let full_message = "Число: ".to_string() + &number.to_string();
    println!("{}", full_message); // Вывод: Число: 42
}

Альтернатива: макрос format!

Если вам нужно сразу вставить число в строку, используйте макрос format!. Он работает по тому же принципу, что и println!, но возвращает String вместо вывода в консоль:

let number = 42;
let message = format!("Ответ: {}", number); // "Ответ: 42"
let pi = 3.14;
let formatted = format!("π ≈ {:.2}", pi); // "π ≈ 3.14" (работает и с числами с плавающей точкой)

Преобразование в &str

Напрямую преобразовать число в &str нельзя, так как &str — это ссылка на строку, которая должна где-то храниться. Однако вы можете сначала создать String, а затем получить её срез:

let number = 42;
let string_number = number.to_string(); // String
let str_slice: &str = &string_number; // &str, ссылающийся на string_number
// Или короче:
let str_slice = &number.to_string(); // Временная строка, живёт до конца выражения

Преобразование из строки в число (обратная операция)

Для полноты картины: если нужно преобразовать строку в число, используйте метод parse():

let text = "42";
let number: i32 = text.parse().expect("Не число!"); // 42
// Или с обработкой ошибки:
match text.parse::<i32>() {
    Ok(n) => println!("Число: {}", n),
    Err(e) => println!("Ошибка: {}", e),
}

Производительность и лучшие практики

  • Для единичных преобразований: to_string() — идеальный выбор. Он читаемый и эффективный.
  • Для вставки в шаблоны: используйте format! — он оптимизирован и не создаёт лишних промежуточных строк.
  • Для массовых преобразований (например, в цикле): рассмотрите itoa (крейт для быстрого преобразования чисел в строки), но для 99% случаев встроенный to_string() работает достаточно быстро.

Полный пример

fn main() {
    // Разные целочисленные типы
    let a: i32 = -100;
    let b: u64 = 255;
    let c: usize = 1024;
    
    println!("{}", a.to_string()); // "-100"
    println!("{}", b.to_string()); // "255"
    println!("{}", c.to_string()); // "1024"
    
    // Форматирование с основанием системы счисления
    println!("{:b}", 42); // "101010" (двоичная)
    println!("{:x}", 255); // "ff" (шестнадцатеричная)
    println!("{:o}", 8); // "10" (восьмеричная)
}

Запомните: to_string() — ваш главный инструмент. Он работает для любых чисел и большинства других типов, которые можно отобразить в виде строки.

<<>>

Использование крейта itoa для максимальной производительности

Если вы пишете высоконагруженный код, где преобразование чисел в строки происходит в критическом участке (например, в цикле с миллионами итераций), встроенный to_string() может быть не самым быстрым вариантом. В таких случаях стоит использовать крейт itoa.

Пример использования:

// Добавьте в Cargo.toml: itoa = "1.0"
use itoa;

fn main() {
    let number: i32 = 42;
    let mut buffer = itoa::Buffer::new(); // Буфер для повторного использования
    let s = buffer.format(number); // &str, без аллокации
    println!("{}", s); // "42"
}

itoa работает быстрее за счёт:

  • Отсутствия аллокации на куче (использует стековый буфер).
  • Оптимизированного алгоритма преобразования.

Однако для обычных задач (вывод в лог, формирование сообщений пользователю) to_string() более чем достаточен. Используйте itoa только если профилирование показало, что преобразование чисел является узким местом.

Сравнение скорости (неофициальное):

// to_string(): ~50 нс на число (с аллокацией)
// itoa: ~10 нс на число (без аллокации)

Также обратите внимание на крейт ryu для чисел с плавающей точкой (f32/f64), если вам нужно быстрое преобразование дробных чисел.