¿Convertir una cadena a int en Rust?

186

Nota: ¡esta pregunta contiene un código anterior a 1.0 obsoleto! Sin embargo, la respuesta es correcta.

Para convertir a stra inten Rust, puedo hacer esto:

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

La única forma en que sé cómo convertir un Stringa intes obtener una porción de él y luego usarlo from_strasí:

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

¿Hay alguna manera de convertir directamente a Stringa int?

mtahmed
fuente
1
Consulte también: stackoverflow.com/q/32381414/500207 para no decimal (es decir, hexadecimal).
Ahmed Fasih
2
Algo obvio, pero una nota para cualquiera que encuentre esta pregunta mucho después de 2014 y se pregunte por qué from_str no está dentro del alcance, no está en el preludio. use std::str::FromStr;arregla eso. Más sobre from_str si lo desea. doc.rust-lang.org/std/str/trait.FromStr.html#tymethod.from_str
7l-l04

Respuestas:

259

Usted puede convertir directamente a un int utilizando el str::parse::<T>()método .

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

Puede especificar el tipo de análisis con el operador turbofish ( ::<>) como se muestra arriba o mediante una anotación explícita de tipo:

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

Como se menciona en los comentarios, parse()devuelve a Result. Este resultado será un Errsi la cadena no se puede analizar como el tipo especificado (por ejemplo, la cadena "peter"no se puede analizar como i32).

John Vrbanac
fuente
35
Tenga en cuenta que parsedevuelve aResult , por lo que debe lidiar con eso adecuadamente para llegar a un tipo integral real.
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>devuelve una Result<u32, core::num::ParseIntError>y Result::unwrap"desenvuelve resultado, produciendo el contenido de un Okpánicos [OR] si el valor es una Err, con un mensaje de pánico proporcionada por el Errvalor 's".

str::parsees una función genérica , de ahí el tipo entre paréntesis angulares.

Jared Beck
fuente
9
Si especifica el tipo de la variable ( let my_u8: u8), entonces no necesita el valor entre paréntesis angulares. También tenga en cuenta que el estilo de Rust predominante indica que :debe mantenerse en el lado izquierdo.
Shepmaster
55
Específicamente, quise decirlet my_u32: u32 = "42".parse().unwrap()
Shepmaster
9

Si obtiene su cadena stdin().read_line, primero debe recortarla.

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

Con una noche reciente, puedes hacer esto:

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

Lo que sucede aquí es que Stringahora se puede desreferenciar en a str. Sin embargo, la función quiere un &str, así que tenemos que pedir prestado nuevamente. Como referencia, creo que este patrón particular ( &*) se llama "préstamo cruzado".

DK
fuente
De acuerdo, no estoy en nightlies, pero lo aceptaré como respuesta, ya que en realidad traté de desreferenciar a un Stringen un punto y esperaba que funcionara.
mtahmed
2
Alternativamente, puede expresarse my_sttring.as_slice()como my_string[](actualmente slicing_syntaxestá controlado por funciones, pero lo más probable es que alguna forma termine en el idioma).
tempestadept
1

Puede usar el método FromStrdel rasgo from_str, que se implementa para i32:

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

Bueno no. ¿Por qué debería haber? Simplemente descarte la cadena si ya no la necesita.

&stres más útil que Stringcuando solo necesita leer una cadena, porque es solo una vista del dato original, no su propietario. Puede pasarlo más fácilmente que String, y es copiable, por lo que no es consumido por los métodos invocados. En este sentido, es más general: si tiene un String, puede pasarlo a donde &strse espera un, pero si lo tiene &str, solo puede pasarlo a las funciones que esperan Stringsi realiza una nueva asignación.

Puede encontrar más información sobre las diferencias entre estos dos y cuándo usarlos en la guía oficial de cadenas .

Vladimir Matveev
fuente
Bueno, una razón obvia de por qué "debería haber", en mi opinión, es que no tendría que hacerlo .as_slice()cada vez que necesito hacerlo from_stren una cadena. Argumentos de línea de comandos, por ejemplo, es un lugar donde tengo que hacer from_stren todos los argumentos a interpretarlos como ints etc
mtahmed
as_slice()es solo un aspecto menor del manejo de cadenas. Por ejemplo, puede usar la sintaxis de corte ( s[]) o explotar la Derefcoerción ( &*s). Incluso hay una propuesta que permitiría escribir solo &s.
Vladimir Matveev
Ooooh! ¿Qué haría &spara una cadena? ¿Daría una strvuelta? ¿Podrías señalarme la propuesta?
mtahmed
1
En primer lugar, strno es con lo que está trabajando; es &str. Son diferentes (pero relacionados). El primero es un tipo de tamaño dinámico que casi nunca usarías directamente, mientras que el segundo es un segmento de cadena que es un puntero grueso. La propuesta se llama coerciones deref ; permitiría coaccionar de &Ta &Usi T: Deref<U>. Desde String: Deref<str>ya, usted será capaz de obtener &stra partir Stringcon sólo &. Todavía está en discusión, pero dudo que suceda antes de 1.0, queda muy poco tiempo.
Vladimir Matveev
-1

¡Así que básicamente quieres convertir una cadena en un entero bien! esto es lo que uso principalmente y eso también se menciona en la documentación oficial.

fn main() {

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

}

Esto funciona tanto para String como para & str Espero que esto también ayude.

Taimoor
fuente