Because dereferencing Vec<T>
(src) results in &[T]
, i.e. given Vec<Vec<u8>>
it results in &[Vec<u8>]
and not &[&[u8]]
.
Ultimately, you'll need to map()
, deref()
/as_slice()
and collect()
to obtain &[&[u8]]
:
let v: Vec<Vec<u8>> = ...;
let v = v.iter().map(std::ops::Deref::deref).collect::<Vec<_>>();
// or
let v = v.iter().map(Vec::as_slice).collect::<Vec<_>>();
bar(&v);
Alternatively depending on the context, you could change bar()
into a generic function and accept IntoIterator
. Then both would be possible:
fn bar<I, T>(iter: I)
where
I: IntoIterator<Item = T>,
T: AsRef<[u8]>,
{
...
}
bar(&vec![&vec![]]);
bar(&vec![&vec![][..]][..]);
The reason &vec![&vec![]]
doesn't work, is because the inner &
doesn't result in the Vec<u8>
to dereference into &[u8]
, but instead just references the Vec
resulting in &Vec<u8>
.
The outer &
then doesn't work, because bar
expects &[&[u8]]
. But it receives &Vec<&Vec<u8>>
and dereferencing to &[&Vec<u8>]
still isn't what bar
expects either. Thus why you receive the mismatched types
error.
Your second example &vec![&vec![][..]][..]
works, because you're explicitly causing both Vec
s to be dereferenced to slices.
This can however be "simplified" into something more readable using as_slice()
, i.e. bar(vec![vec![].as_slice()].as_slice());
.
However, ultimately to get a &[&[u8]]
from an arbitrary Vec<Vec<u8>>
you'd need to deref and collect into a new Vec<&[u8]>
.
Related: "What are Rust's exact auto-dereferencing rules?"