问题
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?
回答1:
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
回答2:
This answer pertains to a pre-1.0 version of Rust and the required functions were removed
You can use std::result::fold function for this. It stops iterating after encountering the first Err.
An example program I just wrote:
fn main() {
println!("{}", go([1, 2, 3]));
println!("{}", go([1, -2, 3]));
}
fn go(v: &[int]) -> Result<Vec<int>, String> {
std::result::fold(
v.iter().map(|&n| is_positive(n)),
vec![],
|mut v, e| {
v.push(e);
v
})
}
fn is_positive(n: int) -> Result<int, String> {
if n > 0 {
Ok(n)
} else {
Err(format!("{} is not positive!", n))
}
}
Output:
Ok([1, 2, 3])
Err(-2 is not positive!)
Demo
来源:https://stackoverflow.com/questions/26368288/how-do-i-stop-iteration-and-return-an-error-when-iteratormap-returns-a-result