Using question mark operator inside map

Example code (does not compile)

use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    let numbers = vec!["8", "9", "1", "3"];
    // works as expected
    let integer = numbers[0].parse::<i64>()?; 
    dbg!(integer);
    // i want it to collect the parsed numbers or return with the first error in the main function
    let integers = numbers.iter().map(|number| number.parse::<i64>()?).collect();
    Ok(())
}

Basically, I want to map a failable function on the elements of an iterator which is to be consumed, and want it to either return the full result or return the first error

It's not possible using map.
You have to use a for loop.

let integers = Vec::new();
for number in numbers {
    integers.push(number.parse::<i64>()?);
}

Alternatively, you can take a look at this crate: fallible_iterator - Rust

That's exactly what impl FromIterator for Result does:

fn main() -> Result<(), Box<dyn Error>> {
    let numbers = vec!["8", "9", "1", "3"];
    // We just move the question mark to the very end of pipeline, after collecting
    let integers = numbers
        .iter()
        .map(|number| number.parse::<i64>())
        // And we explicitly ask to collect into `Result<Vec>`
        .collect::<Result<Vec<_>, _>>()?;
    println!("{:?}", integers);
    Ok(())
}

Playground

12 Likes

thank you, that's exactly what I searched for

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.