Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

rust - How can you easily borrow a Vec<Vec<T>> as a &[&[T]]?

How can you easily borrow a vector of vectors as a slice of slices?

fn use_slice_of_slices<T>(slice_of_slices: &[&[T]]) {
    // Do something...
}

fn main() {
    let vec_of_vec = vec![vec![0]; 10];
    use_slice_of_slices(&vec_of_vec);
}

I will get the following error:

error[E0308]: mismatched types
 --> src/main.rs:7:25
  |
7 |     use_slice_of_slices(&vec_of_vec);
  |                         ^^^^^^^^^^^ expected slice, found struct `std::vec::Vec`
  |
  = note: expected type `&[&[_]]`
             found type `&std::vec::Vec<std::vec::Vec<{integer}>>`

I could just as easily define use_slice_of_slices as

fn use_slice_of_slices<T>(slice_of_slices: &[Vec<T>]) {
    // Do something
}

and the outer vector would be borrowed as a slice and all would work. But what if, just for the sake of argument, I want to borrow it as a slice of slices?

Assuming automatic coercing from &Vec<Vec<T>> to &[&[T]] is not possible, then how can I define a function borrow_vec_of_vec as below?

fn borrow_vec_of_vec<'a, T: 'a>(vec_of_vec: Vec<Vec<T>>) -> &'a [&'a [T]] {
    // Borrow vec_of_vec...
}

To put it in another way, how could I implement Borrow<[&[T]]> for Vec<Vec<T>>?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You cannot.

By definition, a slice is a view on an existing collection of element. It cannot conjure up new elements, or new views of existing elements, out of thin air.

This stems from the fact that Rust generic parameters are generally invariants. That is, while a &Vec<T> can be converted as a &[T] after a fashion, the T in those two expressions MUST match.


A possible work-around is to go generic yourself.

use std::fmt::Debug;

fn use_slice_of_slices<U, T>(slice_of_slices: &[U])
where
    U: AsRef<[T]>,
    T: Debug,
{
    for slice in slice_of_slices {
        println!("{:?}", slice.as_ref());
    }
}

fn main() {
    let vec_of_vec = vec![vec![0]; 10];
    use_slice_of_slices(&vec_of_vec);
}

Instead of imposing what the type of the element should be, you instead accept any type... but place a bound that it must be coercible to [T].

This has nearly the same effect, as then the generic function can only manipulate [T] as a slice. As a bonus, it works with multiple types (any which can be coerced into a [T]).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...