Convertire una stringa in int in Rust?


187

Nota: questa domanda contiene un codice pre-1.0 obsoleto! La risposta è corretta, però.

Per convertire un strin un intin Rust, posso fare questo:

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

L'unico modo in cui so come convertire un Stringin intè di prenderne una fetta e usarla from_strin questo modo:

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

C'è un modo per convertire direttamente un Stringin un int?


1
Vedi anche: stackoverflow.com/q/32381414/500207 per non decimali (es. Esadecimale).
Ahmed Fasih,

2
Un po 'ovvio, ma una nota per chiunque trovi questa domanda ben dopo il 2014 e si chieda perché from_str non rientri nel campo di applicazione, non è nel preludio. use std::str::FromStr;lo risolve. Altro su from_str, se lo desideri. doc.rust-lang.org/std/str/trait.FromStr.html#tymethod.from_str
-l04

Risposte:


261

È possibile convertire direttamente ad un int utilizzando il str::parse::<T>()metodo .

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

Puoi specificare il tipo con cui analizzare con l'operatore turbofish ( ::<>) come mostrato sopra o tramite l'annotazione esplicita del tipo:

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

Come menzionato nei commenti, parse()restituisce a Result. Questo risultato sarà Errse la stringa non può essere analizzata come il tipo specificato (ad esempio, la stringa "peter"non può essere analizzata come i32).


35
Si noti che parserestituisce aResult , quindi è necessario gestirlo in modo appropriato per arrivare a un tipo integrale effettivo.
Shepmaster

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>restituisce a Result<u32, core::num::ParseIntError>e Result::unwrap"Unwraps un risultato, producendo il contenuto di un Ok[o] panico se il valore è un Err, con un messaggio di panico fornito dal Errvalore del".

str::parseè una funzione generica , quindi il tipo tra parentesi angolari.


9
Se si specifica il tipo di variabile ( let my_u8: u8), non è necessario il valore tra parentesi angolari. Si noti inoltre che lo stile Rust prevalente indica che :dovrebbe aderire al lato sinistro.
Shepmaster

5
In particolare, intendevolet my_u32: u32 = "42".parse().unwrap()
Shepmaster

9

Se ottieni la tua corda stdin().read_line, devi prima tagliarla.

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

6

Con un recente nightly, puoi farlo:

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

Quello che sta succedendo qui è che Stringora può essere dereferenziato in a str. Tuttavia, la funzione vuole un &str, quindi dobbiamo prendere di nuovo in prestito. Per riferimento, credo che questo particolare modello ( &*) sia chiamato "prestito incrociato".


Va bene, non sono un ragazzo di notte ma lo accetterò come risposta, dato che in realtà ho cercato di dereferenziare un Stringpunto e speravo che funzionasse.
mtahmed,

2
In alternativa, puoi esprimere my_sttring.as_slice()come my_string[](al momento slicing_syntaxè associato a funzionalità, ma molto probabilmente una sua forma finirà nella lingua).
tempestato il

2

Puoi usare il metodo FromStrdel tratto from_str, che è implementato per i32:

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

0

Beh no. Perché dovrebbe esserci? Scarta la stringa se non ti serve più.

&strè più utile di Stringquando è necessario leggere solo una stringa, poiché è solo una vista nella porzione di dati originale, non il suo proprietario. Puoi passarlo più facilmente di String, ed è copiabile, quindi non viene utilizzato dai metodi invocati. A questo proposito è più generale: se hai un String, puoi passarlo dove &strè previsto, ma se lo hai &str, puoi passarlo solo alle funzioni aspettandoti Stringse fai una nuova allocazione.

Puoi trovare ulteriori informazioni sulle differenze tra questi due e su quando usarli nella guida alle stringhe ufficiale .


Bene, una ragione ovvia per cui "ci dovrebbe essere", secondo me, è che non dovrei fare .as_slice()ogni volta che devo fare from_strsu una stringa. Gli argomenti della riga di comando, ad esempio, sono un posto dove devo fare from_strsu tutti gli argomenti per interpretarli come ints ecc.
mtahmed,

as_slice()è solo un aspetto secondario della gestione delle stringhe. Ad esempio, è possibile utilizzare la sintassi di slicing ( s[]) o sfruttare Derefcoercion ( &*s). C'è anche una proposta che consentirebbe di scrivere solo &s.
Vladimir Matveev,

Ooooh! Cosa farebbe &sper una stringa? Ne darebbe un strritorno? Potresti indicarmi la proposta?
mtahmed,

1
Prima di tutto, strnon è quello con cui stai lavorando; lo è &str. Sono diversi (ma correlati). Il primo è un tipo di dimensioni dinamiche che non useresti quasi mai direttamente, mentre il secondo è una sezione di stringa che è un puntatore grasso. La proposta si chiama deref coercions ; consentirebbe di forzare da &Ta &Use T: Deref<U>. Da String: Deref<str>già, sarai in grado di ottenere &strda Stringsolo &. È ancora in discussione, ma dubito che accadrà prima dell'1: è rimasto troppo poco tempo.
Vladimir Matveev,

-1

Quindi in pratica vuoi convertire una stringa in un numero intero! ecco quello che uso principalmente e che è anche menzionato nella documentazione ufficiale ..

fn main() {

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

}

Questo funziona sia per String che per Str. Spero che anche questo possa aiutare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.