Избегать "не может выйти из заимствованного контента" без использования "to_vec"? - PullRequest
1 голос
/ 06 марта 2019

Я изучаю ржавчину и имею простую программу, показанную ниже. Ссылка на игровую площадку .

#[derive(Debug)]
pub struct Foo {
    bar: String,
}

pub fn gather_foos<'a>(data: &'a Vec<Vec<&'a Foo>>) -> Vec<Vec<&'a Foo>> {
    let mut ret: Vec<Vec<&Foo>> = Vec::new();

    for i in 0..data.len() {
        if meets_requirements(&data[i]) {
            ret.push(data[i].to_vec());
        }
    }

    return ret
}

fn meets_requirements<'a>(_data: &'a Vec<&'a Foo>) -> bool {
    true
}

fn main() {
    let foo = Foo{
        bar: String::from("bar"),
    };
    let v1 = vec![&foo, &foo, &foo];
    let v2 = vec![&foo, &foo];
    let data = vec![v1, v2];

    println!("{:?}", gather_foos(&data));
}

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

Я уверен, что есть более эффективный способ сделать это без необходимости вызывать to_vec(), который мне пришлось реализовать, чтобы избежать ошибки cannot move out of borrowed content, но я не уверен, что это за решение.

Я сейчас узнаю о Box<T> и думаю, что это может помочь решить мои потребности? Спасибо за любую помощь !!

1 Ответ

1 голос
/ 06 марта 2019

Ошибка появляется, потому что вы пытаетесь переместить владение одним из векторов во входном векторе в выходной вектор, что недопустимо, поскольку вы неизменно заимствовали входной вектор. to_vec() создает копию, поэтому она работает, когда вы ее используете.

Решение зависит от того, что вы пытаетесь сделать. Если вам не нужен исходный ввод (вам нужны только совпадающие), вы можете просто передать ввод по значению, а не по ссылке, что позволит вам использовать вектор и перемещать элементы на выход. Вот пример этого .

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

Для других случаев есть другие варианты. Если вам по какой-то причине необходимо, чтобы данные принадлежали нескольким элементам, вы можете попробовать Rc<T> или Arc<T> для интеллектуальных указателей с подсчетом ссылок, которые можно клонировать для обеспечения неизменного доступа к одним и тем же данным несколькими владельцами.

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