respiratorias resfriada remedios quitar porque por para niños nasal nariz muelas muela mucho intenso estoy estornudo dolor curar congestion como comezon caseros alergias alergia rust

rust - resfriada - remedios caseros para la alergia nasal



¿Cómo detengo la iteración y devuelvo un error cuando Iterator:: map devuelve un Result:: Err? (2)

Esta respuesta se refiere a una versión anterior a la versión 1.0 de Rust y se eliminaron las funciones necesarias

Puede usar la función std::result::fold para esto. Deja de iterar después de encontrar el primer Err .

Un programa de ejemplo que acabo de escribir:

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)) } }

Salida:

Ok([1, 2, 3]) Err(-2 is not positive!)

Demo

Tengo una función que devuelve un Result :

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

Luego otro usándolo así:

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

¿Cómo manejo el caso de falla dentro de cualquiera de las iteraciones del map ?

Sé que podría usar flat_map y en este caso los resultados del error serían ignorados :

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

El iterador del resultado tiene 0 o 1 elementos dependiendo del estado de éxito, y flat_map lo filtrará si es 0.

Sin embargo, no quiero ignorar los errores. En su lugar, quiero hacer que todo el bloque de código se detenga y devuelva un nuevo error (basado en el error que apareció en el mapa, o simplemente reenviar el error existente).

¿Cómo manejo esto en Rust?


Result implementa FromIterator , por lo que puede mover el Result exterior y los iteradores se encargarán del resto (incluida la detención de la iteración si se encuentra un error).

#[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