str::parse¶
Level: reference · for working programmers
One line: Parses the string into any type implementing FromStr, returning Result — and the target type is chosen by inference, not by the method name.
Stable since 1.0.0.
"42".parse::<i32>() and let n: i32 = "42".parse()? are the same call. The turbofish and the annotation are two ways to tell the compiler which FromStr to use; leave both out and you get E0282, type annotations needed, which is the most common first encounter with this method.
It does not trim. " 42".parse::<i32>() is an error — a leading space is not part of any integer's grammar. Call trim first on anything a human typed; this is the single most common parse bug.
The error type is F::Err, which differs per target — ParseIntError, ParseFloatError, AddrParseError. That matters when you write a function returning Result<_, Box<dyn Error>> and mix them.
+ is accepted for numbers ("+7" parses); f64 accepts inf and NaN; bool accepts exactly "true" and "false", not "True" or "1". Your own type joins in by implementing FromStr.
Example¶
str_parse.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
use std::str::FromStr;
#[derive(Debug)]
struct Rgb(u8, u8, u8);
impl FromStr for Rgb {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let parts: Vec<&str> = s.split(',').map(str::trim).collect();
match parts.as_slice() {
[r, g, b] => Ok(Rgb(
r.parse().map_err(|_| format!("bad red: {r}"))?,
g.parse().map_err(|_| format!("bad green: {g}"))?,
b.parse().map_err(|_| format!("bad blue: {b}"))?,
)),
_ => Err(format!("want 3 parts, got {}", parts.len())),
}
}
}
fn main() {
// Two spellings of the same call; the type is chosen by inference.
println!("{:?}", "42".parse::<i32>());
let n: i32 = "42".parse().unwrap();
println!("{n}");
// It does not trim.
println!("{:?}", " 42".parse::<i32>().is_err());
println!("{:?}", " 42".trim().parse::<i32>());
// Per-type grammars.
println!("{:?}", "+7".parse::<i32>());
println!("{:?}", "3.5".parse::<f64>());
println!("{:?}", "true".parse::<bool>());
println!("{:?}", "True".parse::<bool>().is_err());
println!("{:?}", "300".parse::<u8>().is_err());
// Your own type.
let colour = "12, 34,56".parse::<Rgb>();
println!("{colour:?}");
if let Ok(Rgb(r, g, b)) = colour {
println!("red {r}, green {g}, blue {b}");
}
println!("{:?}", "12,34".parse::<Rgb>());
println!("{:?}", "12,34,300".parse::<Rgb>());
}
Verified output of str_parse.rs — regenerated by tools/run_examples.py, never hand-typed.
Ok(42)
42
true
Ok(42)
Ok(7)
Ok(3.5)
Ok(true)
true
true
Ok(Rgb(12, 34, 56))
red 12, green 34, blue 56
Err("want 3 parts, got 2")
Err("bad blue: 300")
See also¶
str::trim— what to call first on input a person typedstr::split_once— splitting the fields before parsing them- Making a
String— the opposite direction, viato_stringand its four rivals String::new— where the text usually came from
str::parse in the standard library ↗
Po polsku¶
Typ wyniku wybiera tu wnioskowanie typów, a nie nazwa metody: "42".parse::<i32>() i let n: i32 = "42".parse()? to jedno i to samo wywołanie, raz zapisane turbofishem, raz adnotacją typu. Kiedy zabraknie obu, kompilator nie ma skąd wziąć właściwej implementacji FromStr i wypisuje E0282, type annotations needed — to zwykle pierwsze spotkanie z tym błędem i nie oznacza ono, że w kodzie jest coś zepsutego, tylko że brakuje jednej informacji.
Ważniejsza dla nas jest inna sprawa: parse nie zna żadnych ustawień regionalnych. "3,5".parse::<f64>() skończy się błędem, bo gramatyka f64 zna wyłącznie kropkę — polski przecinek dziesiętny trzeba zamienić samodzielnie, choćby przez s.replace(',', "."), podobnie jak spacje z zapisu „1 000 000”. Nie ma też żadnego przycinania: " 42".parse::<i32>() to Err, więc na wszystkim, co wpisał człowiek, wołaj najpierw trim. Ta sama dosłowność dotyczy bool, który przyjmuje dokładnie "true" i "false" — ani "True", ani "1", a już na pewno nie "tak".
Szukaj po polsku: konwersja tekstu na liczbę · przecinek dziesiętny a kropka · rust parse E0282 type annotations needed · rust implement FromStr