Result
を返す関数があります。
fn find(id: &Id) -> Result<Item, ItemError> {
// ...
}
次に、次のように使用します:
let parent_items: Vec<Item> = parent_ids.iter()
.map(|id| find(id).unwrap())
.collect();
map
のいずれかの反復内で失敗した場合の処理方法を教えてください。
flat_map
そしてこの場合のエラー結果は無視されます:
let parent_items: Vec<Item> = parent_ids.iter()
.flat_map(|id| find(id).into_iter())
.collect();
Result
のイテレータには、成功状態に応じて0または1のアイテムがあり、flat_map
は、0の場合、フィルターで除外します。
しかし、私はignoreエラーをしたくありません。代わりに、コードブロック全体を停止して新しいエラーを返します(マップ内で発生したエラーに基づいて、または単に既存のエラー)。
Rustでこれを最適に処理するにはどうすればよいですか?
Result
implements FromIterator
なので、Result
を外側に移動すると、イテレータが残りの処理を行います(エラーが見つかった場合の反復の停止を含む) )。
#[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);
}
この回答は、1.0より前のバージョンのRustに関係し、必要な関数が削除されました
std::result::fold
このための関数。最初のErr
が検出されると、反復が停止します。
私が書いたプログラム例:
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))
}
}
出力:
Ok([1, 2, 3])
Err(-2 is not positive!)