Как преобразовать строку (String) в целое число (int) в Rust?
Основной способ: метод parse()
В Rust для преобразования строки в целое число используется метод parse(), который доступен для типа str (строковый срез). Он возвращает Result, поэтому нужно обрабатывать возможную ошибку парсинга.
Вот правильный способ:
fn main() {
let input = String::from("42");
// Преобразуем String в &str (автоматически через заимствование)
// и вызываем parse()
let number: i32 = input.parse().unwrap(); // .unwrap() - упрощённо для примера
println!("Число: {}", number); // Выведет: Число: 42
}
Но в реальном коде никогда не используйте .unwrap() — это приведёт к панике при невалидном вводе. Вместо этого обрабатывайте Result:
Обработка ошибок (рекомендуемый способ)
fn main() {
let inputs = vec!["42", " 10 ", "abc", "99999999999999999", "3.14"];
for input in inputs {
// Метод trim() удаляет пробелы, parse() пытается распарсить
match input.trim().parse::<i32>() {
Ok(number) => println!("Успех: '{}' -> {}", input, number),
Err(e) => println!("Ошибка для '{}': {}", input, e),
}
}
// Вывод:
// Успех: '42' -> 42
// Успех: ' 10 ' -> 10
// Ошибка для 'abc': invalid digit found in string
// Ошибка для '99999999999999999': number too large to fit in target type
// Ошибка для '3.14': invalid float literal
}
Детальное объяснение
parse()— это generic-метод, тип результата указывается либо через аннотацию типа (: i32), либо через "турбо-рыбу" (::<i32>).trim()удаляет пробелы и непечатные символы в начале и конце строки.- Ошибки:
parse()вернётErrесли строка содержит нецифровые символы, число выходит за пределы типа, или строка пуста. - Для разных типов:
i32,u64,i8,usizeи т.д. — все они реализуют трейтFromStr, поэтомуparse()работает для любых целочисленных типов.
Работа с большими строками и производительностью
Если вам нужно парсить много строк, избегайте создания лишних копий. Используйте &str напрямую:
fn parse_number(s: &str) -> Option<i32> {
s.trim().parse().ok() // .ok() преобразует Result в Option
}
fn main() {
let data = "100\n200\nabc\n300";
let sum: i32 = data
.lines()
.filter_map(parse_number)
.sum();
println!("Сумма чисел: {}", sum); // 600
}
Метод .ok() преобразует Result<T, E> в Option<T>, отбрасывая ошибки. Это удобно, когда невалидные строки можно просто игнорировать.
Альтернативный подход: крейт lexical или ручной парсинг
Для высоконагруженных приложений или специфических форматов можно использовать более производительные крейты, например lexical (сейчас lexical-core):
// Cargo.toml: lexical-core = "0.8"
use lexical_core;
fn main() {
let input = b"42"; // Работает с байтами, быстрее
let number: i32 = lexical_core::parse(input).unwrap();
println!("{}", number);
}
Или, если вам нужно реализовать парсинг вручную (например, для обучения):
fn custom_parse(s: &str) -> Option<i32> {
let s = s.trim();
if s.is_empty() { return None; }
let bytes = s.as_bytes();
let mut result: i32 = 0;
let mut negative = false;
let start = if bytes[0] == b'-' { negative = true; 1 } else { 0 };
for &byte in &bytes[start..] {
if byte < b'0' || byte > b'9' { return None; }
result = result.checked_mul(10)?.checked_add((byte - b'0') as i32)?;
}
if negative { result = result.checked_neg()?; }
Some(result)
}
Этот ручной вариант использует checked_* методы для предотвращения переполнения. Для большинства задач стандартного parse() более чем достаточно — он оптимизирован и покрывает все краевые случаи.
Ответов пока нет.
Войдите чтобы оставить ответ