Как вы можете легко заимствовать Vec <Vec <T>> как & [& [T]]? - PullRequest
0 голосов
/ 27 апреля 2018

Как вы можете легко заимствовать вектор векторов как кусочек среза?

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);
}

Я получу следующую ошибку:

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}>>`

Я мог бы так же легко определить use_slice_of_slices, как

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

и внешний вектор будет заимствован как срез, и все будет работать. Но что, если ради аргумента я хочу позаимствовать его как кусочек?

Если автоматическое приведение от &Vec<Vec<T>> к &[&[T]] невозможно, то как я могу определить функцию borrow_vec_of_vec, как показано ниже?

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

Другими словами, как я могу реализовать Borrow<[&[T]]> для Vec<Vec<T>>?

1 Ответ

0 голосов
/ 27 апреля 2018

Вы не можете .

По определению, срез представляет собой представление существующего набора элементов. Он не может вызвать в воображении новые элементы или новые представления о существующих элементах из воздуха.

Это связано с тем фактом, что универсальные параметры Rust обычно инварианты . То есть, хотя &Vec<T> может быть преобразовано как &[T] после моды, T в этих двух выражениях ДОЛЖНЫ совпадать.


Возможный обходной путь - это сделать себя самостоятельно.

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);
}

Вместо того, чтобы навязывать тип элемента, вы вместо этого принимаете любой тип ... но ставите границу, что он должен быть принудительно приведен к [T].

Это имеет почти тот же эффект, что и общая функция может манипулировать только [T] как срезом. В качестве бонуса он работает с несколькими типами (любой из которых может быть приведен к [T]).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...