Преобразовать строку в int в Rust?


187

Примечание: этот вопрос содержит устаревший код до 1.0! Ответ правильный, хотя.

Чтобы преобразовать strв intв Русте, я могу это сделать:

let my_int = from_str::<int>(my_str);

Единственный способ, которым я знаю, как преобразовать a Stringв a, intсостоит в том, чтобы получить его часть, а затем использовать from_strего следующим образом:

let my_int = from_str::<int>(my_string.as_slice());

Есть ли способ напрямую преобразовать Stringв int?


1
См. Также: stackoverflow.com/q/32381414/500207 для недесятичной (то есть шестнадцатеричной).
Ахмед Фасих

2
Несколько очевидно, но замечание для любого, кто найдет этот вопрос намного позже 2014 года и задается вопросом, почему from_str не входит в сферу применения, он не входит в прелюдию. use std::str::FromStr;исправляет это. Больше на from_str, если хотите. doc.rust-lang.org/std/str/trait.FromStr.html#tymethod.from_str
7-1104

Ответы:


261

Вы можете напрямую конвертировать в int, используя str::parse::<T>()метод .

let my_string = "27".to_string();  // `parse()` works with `&str` and `String`!
let my_int = my_string.parse::<i32>().unwrap();

Вы можете указать тип для анализа с помощью оператора turbofish ( ::<>), как показано выше, или с помощью явной аннотации типа:

let my_int: i32 = my_string.parse().unwrap();

Как указано в комментариях, parse()возвращает Result. Этот результат будет, Errесли строка не может быть проанализирована как указанный тип (например, строка "peter"не может быть проанализирована как i32).


35
Обратите внимание, что parseвозвращает aResult , поэтому вам нужно соответствующим образом разобраться с этим, чтобы получить фактический целочисленный тип.
Шепмастер

54
let my_u8: u8 = "42".parse::<u8>().unwrap();
let my_u32: u32 = "42".parse::<u32>().unwrap();

// or, to be safe, match the `Err`
match "foobar".parse::<i32>() {
  Ok(n) => do_something_with(n),
  Err(e) => weep_and_moan(),
}

str::parse::<u32>возвращает a Result<u32, core::num::ParseIntError>и Result::unwrap«разворачивает результат, получая содержимое Okпаники [или], если значение равно Err, с сообщением паники, предоставленным Errзначением s».

str::parseявляется универсальной функцией , поэтому тип в угловых скобках.


9
Если вы укажете тип переменной ( let my_u8: u8), вам не понадобится значение в угловых скобках. Также обратите внимание, что преобладающий стиль Rust указывает на то, что :следует придерживаться левой стороны.
Шепмастер

5
В частности, я имел в видуlet my_u32: u32 = "42".parse().unwrap()
Шепмастер

9

Если вы получили свою строку stdin().read_line, вы должны сначала обрезать ее.

let my_num: i32 = my_num.trim().parse()
   .expect("please give me correct string number!");

6

С недавнего вечера вы можете сделать это:

let my_int = from_str::<int>(&*my_string);

То, что происходит здесь, Stringтеперь может быть разыменовано в str. Тем не менее, функция хочет &str, поэтому мы должны снова позаимствовать. Для справки, я считаю, что этот конкретный шаблон ( &*) называется «перекрестное заимствование».


Хорошо, я не на ночных вечерах, но я приму это как ответ, так как я действительно пытался разыменовать a Stringв одном месте и надеялся, что это сработает.
mtahmed

2
В качестве альтернативы, вы можете выразить my_sttring.as_slice()как my_string[](в настоящее время slicing_syntaxэто функциональный, но, скорее всего, какая-то его форма окажется в языке).
tempestadept


0

Ну нет. Почему там должно быть? Просто отбросьте строку, если она вам больше не нужна.

&strэто более полезно, чем Stringкогда вам нужно только прочитать строку, потому что это только просмотр исходного фрагмента данных, а не его владельца. Вы можете передать его более легко, чем String, и он может быть скопирован, поэтому он не используется вызываемыми методами. В этом отношении он является более общим: если у вас есть String, вы можете передать его туда, где &strожидается, но если у вас есть &str, вы можете передать его только функциям, ожидающим, Stringесли вы сделаете новое распределение.

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


Ну, очевидная причина того, почему «должно быть», на мой взгляд, заключается в том, что мне не нужно было бы делать .as_slice()каждый раз, когда мне нужно делать from_strсо строкой. Например, аргументы командной строки - это единственное место, где мне нужно сделать from_strвсе аргументы, чтобы интерпретировать их как ints и т. Д.
mtahmed

as_slice()это только второстепенный аспект обработки строк. Например, вы можете использовать синтаксис нарезки ( s[]) или использовать Derefcoercion ( &*s). Есть даже предложение, которое позволило бы написать просто &s.
Владимир Матвеев

Оооо! Что бы &sсделать для строки? Это даст strназад? Не могли бы вы указать мне на предложение?
mtahmed

1
Прежде всего, strэто не то, с чем вы работаете; это так &str. Они разные (но связанные). Первый тип представляет собой динамически изменяемый тип, который вы почти никогда не будете использовать напрямую, а второй - фрагмент строки, который является толстым указателем. Предложение называется deref принуждения ; это позволило бы привести &Tк &Uесли T: Deref<U>. Поскольку String: Deref<str>уже вы сможете получить &strс Stringпомощью только что &. Это все еще обсуждается, но я сомневаюсь, что это произойдет до 1.0 - осталось слишком мало времени.
Владимир Матвеев

-1

Таким образом, в основном вы хотите преобразовать строку в целое число правильно! вот что я в основном использую, и это также упоминается в официальной документации ..

fn main() {

    let char = "23";
    let char : i32 = char.trim().parse().unwrap();
    println!("{}", char + 1);

}

Это работает как для String, так и & str. Надеюсь, это тоже поможет.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.