Convertir une chaîne en int dans Rust?

209

Remarque: cette question contient du code pré-1.0 obsolète! La réponse est cependant correcte.

Pour convertir un stren un intdans Rust, je peux faire ceci:

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

La seule façon de savoir comment convertir un Stringen un intest d'en obtenir une tranche et de l'utiliser from_strcomme ceci:

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

Existe-t-il un moyen de convertir directement un Stringen un int?

mtahmed
la source
1
Voir aussi: stackoverflow.com/q/32381414/500207 pour non-décimal (c'est-à-dire hexadécimal).
Ahmed Fasih
2
Un peu évident, mais une note à tous ceux qui trouvent cette question bien après 2014 et se demandent pourquoi from_str n'est pas dans la portée, ce n'est pas dans le prélude. use std::str::FromStr;corrige cela. Plus d'informations sur from_str si vous le souhaitez. doc.rust-lang.org/std/str/trait.FromStr.html#tymethod.from_str
cryptograthor

Réponses:

288

Vous pouvez directement convertir en un entier en utilisant la str::parse::<T>()méthode .

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

Vous pouvez soit spécifier le type à analyser avec l'opérateur turbofish ( ::<>) comme indiqué ci-dessus, soit via une annotation de type explicite:

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

Comme mentionné dans les commentaires, parse()renvoie un fichier Result. Ce résultat sera un Errsi la chaîne n'a pas pu être analysée comme le type spécifié (par exemple, la chaîne "peter"ne peut pas être analysée comme i32).

John Vrbanac
la source
37
Notez que parserenvoie aResult , vous devez donc gérer cela de manière appropriée pour obtenir un type intégral réel.
Shepmaster
55
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>renvoie a Result<u32, core::num::ParseIntError>et Result::unwrap"Développe un résultat, ce qui donne le contenu d'un Ok[ou] panique si la valeur est an Err, avec un message de panique fourni par la Errvaleur de."

str::parseest une fonction générique , d'où le type entre chevrons.

Jared Beck
la source
9
Si vous spécifiez le type de la variable ( let my_u8: u8), vous n'avez pas besoin de la valeur entre crochets angulaires. Notez également que le style de rouille qui prévaut indique qu'il :doit rester du côté gauche.
Shepmaster
5
Plus précisément, je voulais direlet my_u32: u32 = "42".parse().unwrap()
Shepmaster
12

Si vous obtenez votre chaîne stdin().read_line, vous devez d'abord la couper.

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

Avec une soirée récente, vous pouvez faire ceci:

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

Ce qui se passe ici, c'est qu'il Stringpeut maintenant être déréférencé en un fichier str. Cependant, la fonction veut un &str, donc nous devons emprunter à nouveau. Pour référence, je crois que ce modèle particulier ( &*) est appelé «emprunt croisé».

DK.
la source
D'accord, je ne suis pas sur les nightlies mais je l'accepterai comme une réponse car j'ai en fait essayé de déréférencer un Stringà un moment donné et espéré que cela fonctionnerait.
mtahmed
2
Alternativement, vous pouvez exprimer my_sttring.as_slice()comme my_string[]( slicing_syntaxest actuellement limité par les fonctionnalités, mais très probablement une forme de celui-ci se retrouverait dans la langue).
tempestadept
4

Vous pouvez utiliser la méthode FromStrdu trait from_str, qui est implémentée pour i32:

let my_num = i32::from_str("9").unwrap_or(0);
Karthik Cherukuri
la source
2

Et bien non. Pourquoi devrait-il y en avoir? Jetez simplement la chaîne si vous n'en avez plus besoin.

&strest plus utile que Stringlorsque vous n'avez besoin de lire qu'une chaîne, car il ne s'agit que d'une vue de la donnée d'origine, pas de son propriétaire. Vous pouvez le transmettre plus facilement que String, et il est copiable, il n'est donc pas consommé par les méthodes appelées. À cet égard, c'est plus général: si vous avez un String, vous pouvez le passer à l'endroit où un &strest attendu, mais si vous l'avez &str, vous ne pouvez le passer qu'aux fonctions attendues Stringsi vous faites une nouvelle allocation.

Vous pouvez en savoir plus sur les différences entre ces deux et quand les utiliser dans le guide officiel des chaînes .

Vladimir Matveev
la source
Eh bien, une raison évidente pour laquelle "il devrait y avoir", à mon avis, est que je n'aurais pas à faire à .as_slice()chaque fois que je dois le faire from_strsur une chaîne. Les arguments de ligne de commande, par exemple, sont un endroit où je dois faire from_strsur tous les arguments pour les interpréter comme ints etc.
mtahmed
as_slice()n'est qu'un aspect mineur de la gestion des chaînes. Par exemple, vous pouvez utiliser la syntaxe de découpage ( s[]) ou exploiter la Derefcoercition ( &*s). Il existe même une proposition qui permettrait d'écrire juste &s.
Vladimir Matveev
Ooooh! Que ferait &spour une chaîne? Cela rendrait-il un strretour? Pouvez-vous m'indiquer la proposition?
mtahmed
1
Tout d'abord, ce strn'est pas ce avec quoi vous travaillez; ça l'est &str. Ils sont différents (mais liés). Le premier est un type de taille dynamique que vous n'utiliseriez presque jamais directement, tandis que le second est une tranche de chaîne qui est un gros pointeur. La proposition est appelée des coercitions de déréf ; cela permettrait de contraindre de &Tà &Usi T: Deref<U>. Depuis String: Deref<str>déjà, vous serez en mesure d'obtenir à &strpartir Stringavec juste &. Il est toujours en discussion mais je doute que cela se produise avant la version 1.0 - il reste trop peu de temps.
Vladimir Matveev
-1

Donc, fondamentalement, vous voulez convertir une chaîne en un entier droit! voici ce que j'utilise le plus souvent et qui est également mentionné dans la documentation officielle ..

fn main() {

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

}

Cela fonctionne à la fois pour String et & str J'espère que cela aidera aussi.

Taimoor
la source