Как преобразовать строку (String или &str) в число (int) в Rust?
Решение: метод parse() с явным указанием типа
В Rust нет неявного преобразования между строками и числами. Для конвертации используется метод parse(), который доступен для типа String и &str. Этот метод возвращает Result, поэтому нужно обработать возможную ошибку.
Вот правильный способ преобразования строки в целое число:
use std::io;
fn main() {
let mut input = String::new();
io::stdin().read_line(&mut input)
.expect("Не удалось прочитать строку");
// Удаляем символ новой строки и пробелы
let trimmed = input.trim();
// Преобразуем строку в i32 с обработкой ошибки
let number: i32 = match trimmed.parse() {
Ok(num) => num,
Err(e) => {
eprintln!("Ошибка преобразования: {}", e);
return;
}
};
println!("Введённое число: {}", number + 10);
}
Объяснение по шагам:
- trim() — удаляет пробельные символы (включая перевод строки \n) с начала и конца строки. Без этого parse() может не сработать.
- parse() — обобщённый метод, который пытается преобразовать строку в целевой тип. Тип вывода определяется контекстом (в нашем случае — аннотацией
: i32). - match — обрабатывает результат: Ok(num) — успешное преобразование, Err(e) — ошибка (например, если введён текст).
Альтернативные способы указания типа:
// Через "turbofish" синтаксис
let number = trimmed.parse::<i32>();
// Через expect для паники при ошибке (не рекомендуется для продакшена)
let number: i32 = trimmed.parse().expect("Введите корректное число!");
Другие целочисленные типы:
Вы можете использовать любой целочисленный тип: i8, i16, i32, i64, u8, u32 и т.д. Для больших чисел подойдёт i64 или u64.
let small: u8 = "255".parse().expect("Слишком большое число");
let big: i64 = "9223372036854775807".parse().expect("Переполнение");
Преобразование числа обратно в строку:
Для обратной операции используйте метод to_string():
let num = 42;
let s = num.to_string(); // "42"
Этот подход гарантирует безопасность типов в Rust и предотвращает ошибки, связанные с неявным преобразованием, которые часто встречаются в других языках.
<<Использование крейта anyhow для упрощения обработки ошибок
Если вы работаете над проектом, где нужно часто конвертировать строки в числа, рекомендую использовать крейт anyhow (или thiserror). Он позволяет избавиться от громоздких конструкций match:
use anyhow::{Result, Context};
use std::io;
fn read_number() -> Result<i32> {
let mut input = String::new();
io::stdin().read_line(&mut input)
.context("Не удалось прочитать ввод")?;
let number = input.trim()
.parse::<i32>()
.context("Введено не число")?;
Ok(number)
}
fn main() -> Result<()> {
let num = read_number()?;
println!("Число: {}", num + 10);
Ok(())
}
Преимущества:
- Оператор
?автоматически пробрасывает ошибки наверх. - Контекстные сообщения помогают быстро понять, где произошла ошибка.
- Код становится чище и ближе к стилю Python.
Добавьте anyhow = "1.0" в Cargo.toml и используйте этот подход для обработки ввода в реальных приложениях.