Get the underlying vec of an iterator?

std::env::args_os() gives an ArgsOs iterator, which stores the result of sys::args::args(), which collects command line arguments upfront. I read up on why it first collects it into a vec before giving it out to iterate over, and I get it, but since the work was done collecting it into a vec I'd like to get that vec without iterating over it a second time.

Of course, I will iterate over it eventually, but if I had the vec I could work with it in-place instead of creating a second vec copy items into.

Is it possible to get the vec of an ArgsOs without recollecting it?

Is it possible to do with iterators that have a struct field that holds a vec instead of the result of something.into_iter()?

The standard library has mechanisms to allow .collect::<Vec<_>>() (or Vec::from_iter()) on an iterator to produce an already-allocated Vec instead of a new one. For example, some_i32_vec.into_iter().map(|value| value + 1).collect::<Vec<i32>>() will return the same vector repurposed. Unfortunately, args_os() does not opt in to that functionality.

However, there isn’t likely much point in making, or worrying about the lack of, this optimization, because starting a process is overall much more expensive than one extra Vec allocation, so it would be quite insignificant in nearly all use cases.

4 Likes

I appreciate your answer. Knowingly doing unnecessary work is always a bummer though..

Unfortunately, args_os() does not opt in to that functionality

Do you happen to know if it was intentional (i.e. API design), or if it just didn't need to implement that functionality when those standard library mechanisms became available?

No, I don’t have any specific information about this. Generally, though, there are plenty of things that could exist in the standard library but haven’t been done yet. If you look at the Rust release notes, you’ll find plenty of “added this trait implementation” that could have been in Rust 1.0 but weren’t. Each one needs someone to think of it and write it.

1 Like