Two ways of to create vec of slices, one with error

So, I can create this with no error and it works, but what good is it if I don't know why

vec![&[1, 3, 6, 1, 2, 1, 1, 1, 0]],

This, on the other hand, tells me that collect can't be called due to unsatisfied trait bounds

(&[1, 3, 6, 1, 2, 1, 1, 1, 0]).collect::<Vec<&[u32]>>()

Why? Is it because collect is usually transforming one thing "into" a collection??

You can only call collect on an iterator, and a &[u32; 9] is not an iterator. This will compile:

(&[1, 3, 6, 1, 2, 1, 1, 1, 0]).iter().collect::<Vec<&u32>>()

However you should note that the item type is &u32 producing a vector with nine elements rather than a vector with a single element (that element being a slice of 9 elements). To get a vector of one element like the first example, you can use std::iter::once.

std::iter::once(&[1, 3, 6, 1, 2, 1, 1, 1, 0]).collect::<Vec<&[u32; 9]>>()
4 Likes

Holy strict typing, Batman. So this would be correct?

std::iter::once(&[1, 3, 6, 1, 2, 1, 1, 1, 0], &[1, 3, 6, 1, 2, 1, 1, 5, 0]).collect::<Vec<&[&u32; 9]; 2]>>()

If that is correct, how do I pass the vec to another fn without having the sizes known at compile time? Or maybe I can't?

Of course not, since std::iter::once takes one argument, not two. You'll have to make an "array of arrays":

[&[1, 3, 6, 1, 2, 1, 1, 1, 0], &[1, 3, 6, 1, 2, 1, 1, 5, 0]]
    .iter()
    .copied()
    .collect::<Vec<&[u32; 9]>>()

Playground

If you mean here "can I get rid of that 9 in type definition?", then yes, trivially:

[&[1, 3, 6, 1, 2, 1, 1, 1, 0], &[1, 3, 6, 1, 2, 1, 1, 5, 0]]
    .iter()
    .copied()
    .map(AsRef::as_ref) // The only other change necessary...
    .collect::<Vec<&[u32]>>() // to change the type here

Awesome and thanks!!