`let res: Result<Vec<_>, _> = iterator.iter().map(|x| x.foo()).collect();`
Left to right reading this statement is "iterate over the values and map it to the output of foo for each value. Then collect that map into a vector."
His other example
``` for (i, x) in something.iter_mut().filter(|| {...}).enumerate() { x = (x) * i } ```
can also be read from left to right as "iterate over something, then filter and enumerate the values"
It's much more explanatory than top down structures with 10 lines to explain the same thing.
For a good while my X's were a nightly only experimental API, but slowly and surely they make it into stable. (Hash|Btree)Map's `.entry` methods (and friends) were another example.
Generally speaking these methods are super helpful and someone else already thought of it. From my experience at least.
.. also this article was infuriating hah.
let res = iterator.iter().map(|x| x.foo()).collect::<Result<Vec<_>, _>>()?;Consider:
for item in iterable.iter() {
item.foo()?;
}
You will exit the loop as soon as there is an error. But with .map().collect(), you iterate over the whole list, and then exit if one of the items yield an error.EDIT: Thank you for your answers, it seems I was wrong and it does short-cricuit!
let v: Option<Vec<i32>> = (0..5).map(|i| {
print!("{i} ");
if i == 3 { None } else { Some(i) }
}).collect();
// prints 0 1 2 3One of the issues with type inference, this exact same code does different things depending on whether the result is assigned to `Option<Vec<i32>>` or `Vec<Option<i32>>`
Kind of like how the answer is always ‘traverse’ in Scala.
.collect() gets overloaded a lot to deal with the intricacies of the return type, which usually says a lot about the computation, e.g. Result or HashSet.
Using the question mark in a closure in general is confusing.
Doing ? on the return value of a statement doesn't make sense. Normally ? is used for: here is this Result (I forgot the trait's name), and give me the Ok(), and if it is Err() then RETURN to the caller.
So the function itself must be of type Result<_, _>.
With the lambda in the example it is unclear by reading the code what the ? should do. Stop at the first error and return Err? Or should the return value be Result<Vec<_>, _>?
One can use the try_ functions on an iterator.
Yes it does
> But this also happens elsewhere, because of this ugly inflexability, we cant do:Use and_then:
I get that there's an upfront cost to learning this stuff, but I think he's blaming the language a little too aggressively.