Перетворити рядок в int в Rust?


187

Примітка: це питання містить застарілий код попереднього 1,0! Однак відповідь правильна.

Щоб перетворити strв intв Руста, я можу це зробити:

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

Єдиний спосіб, коли я знаю, як перетворити Stringна, - 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/ Portrait.FromStr.html#tymethod.from_str
7l-l04

Відповіді:


260

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

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

Ви можете або вказати тип для розбору з оператором турбофіш ( ::<>), як показано вище, або за допомогою явного анотації типу:

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

Як згадується в коментарях, parse()повертається a 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), значення вам не потрібно в кутових дужках. Також зауважте, що переважаючий стиль Іржа вказує на те, що він :повинен дотримуватися лівого боку.
Шепмайстер

5
Зокрема, я мав на увазіlet my_u32: u32 = "42".parse().unwrap()
Shepmaster

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тепер можна відкинути на «a» str. Однак функція хоче &str, тому нам доведеться позичати знову. Для довідки, я вважаю, що саме ця модель ( &*) називається «перехресне запозичення».


Гаразд, я не на солов’ї, але прийму це як відповідь, оскільки я насправді намагався знеструмити a Stringв один момент і сподівався, що це спрацює.
mtahmed

2
Крім того, ви можете виразити my_sttring.as_slice()як my_string[](на даний момент slicing_syntaxфункція закрита, але, найімовірніше, якась форма може закінчитися мовою).
tempestadept

2

Можна скористатися методом FromStrознаки from_str, який реалізується для i32:

let my_num = i32::from_str("9").unwrap_or(0);

0

Ну, ні. Чому повинні бути? Просто відкиньте рядок, якщо вона вам більше не потрібна.

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

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


Ну, очевидною причиною, чому "повинно бути", на мій погляд, є те, що мені не довелося б робити .as_slice()щоразу, коли мені потрібно це робити from_strна рядку. Наприклад, аргументи командного рядка - це одне місце, де мені потрібно зробити from_strвсі аргументи, щоб інтерпретувати їх як ints тощо
mtahmed

as_slice()є лише другорядним аспектом оброблення рядків. Наприклад, ви можете використовувати синтаксис нарізки ( s[]) або використовувати Derefпримус ( &*s). Навіть є пропозиція, яка б дозволила писати просто &s.
Володимир Матвєєв

Оооо! Що б &sзробити для струни? Це strповерне? Не могли б ви вказати мені на пропозицію?
mtahmed

1
По-перше, strце не те, з чим ти працюєш; воно є &str. Вони різні (але споріднені). Перший - це тип динамічного розміру, який ви майже ніколи не використовуєте безпосередньо, тоді як другий - це фрагмент рядка, який є жировим покажчиком. Пропозиція називається дереф коеркіонами ; це дозволило б примусити з &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.