Building arrays from iterators

#1

It should be easy/trivial to build arrays from iterators, and panic if the iterator is too long or too short.

A pseudocode from_iterator would just look like:

fn from_iterator(foo) -> [T; N] {
    let a = foo.next().unwrap();
    let b = foo.next().unwrap();
    let c = foo.next().unwrap();
    let d = foo.next().unwrap();
    assert_eq!(foo.next(), None);
    [a, b, c, d]
}
1 Like
#2

If we had const generics, a recursive solution would have to be used instead. We’d just need to make sure the compiler can de-recurse it.

#3

It seems to me like with const generics, fixed-sized arrays should be able to impl FromIterator ala the method you have above.

That said, it’d be nice if there was a solution to avoid panicking too, e.g. doing collect() on Option<[T; N]> which returned None if there is a length mismatch.

#4

I think that the recently stabilized TryFrom trait will be a better fit.

BTW I am still not quite sure why we have FromIterator trait. Why collect can’t use B: From<Self> bound instead of B: FromIterator<Self::Item>? Is there some complexity issues due to the coherency rules? Or was it done only for symmetry with IntoIterator (which also may be considered redundant, but makes for loop integration much nicier)?

1 Like
#5

next could panic, need recursion

#6

It can deal with panics by wrapping the incomplete array in ManuallyDrop and a newtype to drop whatever was already written.

#7

You can always just collect into an arrayvec and into_inner the array out. That way all the special cases are already handled.

(And maybe you’ll find that you’re fine with just an arrayvec anyway.)

2 Likes
#8

well, this is my use-case: https://cybre.tech/SoniEx2/rust.hexchat.hexchat-plugin/src/branch/master/src/lib.rs#L1117-L1168

so. yeah. idk. I’d rather just have a built-in from_iterator for arrays. as we should, anyway (IMO).