A `Result<T, E>` holds either `Ok(T)`, a successful value, or `Err(E)`, an error. Calling `.ok()` turns it into an `Option<T>`: `Ok(value)` becomes `Some(value)`, while `Err(error)` becomes `None`. The error information is discarded. section 9.1.1 section 5.2.2
fn main() {
let user_input = vec![
"8.9",
"Nine point nine five",
"8.0",
"7.6",
"eleventy-twelve",
];
let successful_numbers = user_input
.iter()
.filter_map(|input| input.parse::<f32>().ok())
.collect::<Vec<f32>>();
println!("{:?}", successful_numbers);
}
Here, `.parse::<f32>()` returns a `Result`. Calling `.ok()` gives `.filter_map()` the `Option` it needs, so failed parses are left out. The collected numbers are `[8.9, 8.0, 7.6]`. section 9.1.1
fn main() {
let num_array = ["8", "9", "Hi", "9898989898"];
let mut char_vec = vec![]; #1
for index in 0..5 {
char_vec.push(
num_array
.get(index) #2
.and_then(|number| number.parse::<u32>().ok()) #3
.and_then(|number| char::try_from(number).ok()), #4
);
}
println!("{:?}", char_vec);
}
`.ok()` also lets parsing and character conversion fit into a chain of `.and_then()` calls. Unlike `.filter_map()`, this chain keeps unsuccessful positions as `None`. Different failures therefore look the same at the end. section 9.1.2
Use `.ok()` when you need an `Option` and do not need to know why an operation failed. If the reason matters, remember that `.ok()` does not preserve it. section 9.1.1 section 9.1.2
