One can pass a Vec
to function expecting a slice with implicit coersion :
fn foo(arg: &[u8]) {}
foo(&vec![]); // compiles fine
Why this cannot be extended to nested slices and Vecs?
fn bar(arg: &[&[u8]]) {}
bar(&vec![&vec![]]); // Compilation error
// Can be worked around by explicit conversion to slices
bar(&vec![&vec![][..]][..]);
Because dereferencing Vec<T>
( src ) results in &[T]
, ie 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()
, ie 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]>
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.