Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
731 views
in Technique[技术] by (71.8m points)

rust - How do I stop iteration and return an error when Iterator::map returns a Result::Err?

I have a function that returns a Result:

fn find(id: &Id) -> Result<Item, ItemError> {
    // ...
}

Then another using it like this:

let parent_items: Vec<Item> = parent_ids.iter()
    .map(|id| find(id).unwrap())
    .collect();

How do I handle the case of failure inside any of the map iterations?

I know I could use flat_map and in this case the error results would be ignored:

let parent_items: Vec<Item> = parent_ids.iter()
    .flat_map(|id| find(id).into_iter())
    .collect();

Result's iterator has either 0 or 1 items depending on the success state, and flat_map will filter it out if it's 0.

However, I don't want to ignore errors, I want to instead make the whole code block just stop and return a new error (based on the error that came up within the map, or just forward the existing error).

How do I best handle this in Rust?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Result implements FromIterator, so you can move the Result outside and iterators will take care of the rest (including stopping iteration if an error is found).

#[derive(Debug)]
struct Item;
type Id = String;

fn find(id: &Id) -> Result<Item, String> {
    Err(format!("Not found: {:?}", id))
}

fn main() {
    let s = |s: &str| s.to_string();
    let ids = vec![s("1"), s("2"), s("3")];

    let items: Result<Vec<_>, _> = ids.iter().map(find).collect();
    println!("Result: {:?}", items);
}

Playground


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...