简体   繁体   中英

Why deref coersion doesn't work for nested Vec?

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![][..]][..]);

Example in the playground .

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]> .

Related: "What are Rust's exact auto-dereferencing rules?"

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM