I'd probably make use the FromIterator impl of FuturesOrdered instead of the loop with push_back.
Also you can probably write map(|arg| constructor(arg)) as map(constructor) (though I haven't tested whether it compiles in this case; sometimes these are tricky if the traits don't match 100%).
Probably calling push in a for_each could work. You could also use an ordinary for loop and call next().await, I'm not sure which one is nicer and if the difference matters in any other way (note that the thing is Unpin so calls to next work without issues).
But the overall syntax is kinda awkwark with the async { () }, which is needed to turn the syncronous vec.push(item) call into an async closure. I guess I would be looking for some method that takes a sync closure instead, or even better: which accepts an argument that implements Extend. But I didn't find either.
Yeah, well, I just wrote down what I meant to achieve. I didn't really expect it to work that way.
This creates an extra Vec which will be needlessly allocated and deallocated. But the syntax/readability seems to be a bit better than the approach using for_each and async { () } above. So not sure what's best.
That extend_reserve and extend_one call is basically what I would like to be part of StreamExt instead. Would that be a reasonable feature request? Or are there existing traits which allow to do this without writing it down manually?
P.S.: In practice I will likely just create an intemediate Vec. The allocation/appending won't hurt, I think. But I still see that StreamExt here is a bit limited.
Actually, I could use &constructor instead of constructor as borrowing an Fn + Sync seems to give me an Fn + Send + Sync. (Couldn't the compiler do it implicitly? It's universally working to turn any Fn + Sync into an Fn + Sync + Send, right?) Edit: I created a new thread on that issue here.
const COUNT: usize = 100;
pub fn foo<T, C>(constructor: C) -> Vec<T>
where
T: Send,
C: Fn(usize) -> T + Sync,
{
use rayon::iter::{IntoParallelIterator, ParallelIterator};
- (0..COUNT).into_par_iter().map(constructor).collect()
+ (0..COUNT).into_par_iter().map(&constructor).collect()
}