Как извлечь из Vec элемент, который перемещен в структуру? - PullRequest
1 голос
/ 05 апреля 2019

У меня есть структура, которая содержит Вектор структур, например,

fn main() {
    let x: Vec<Item> = Vec::new(); 
    // assume x is filled with stuff
    do_things_with(x);
}

struct Item {
    value: String,
}

struct Context {
    x: Vec<Item>,
}

impl Context {
    fn get(&mut self, at: usize) -> Item {
        self.x[at]
    }
}

fn do_things_with(x: Vec<Item>) {
    let mut ctx = Context{
        x: x,
    };
    ctx.get(5);
}

У меня есть Vec вещей, и я передаю это некоторой функции, которая создает контекст и сохраняет переданное значение в этой структуре,Затем я хочу посмотреть на элементы в этом Vec, поэтому у меня есть несколько вспомогательных функций, например, 'get', которая получит элемент с указанным индексом.

Это кажется хорошим, и на C или на любом другом языкебыло бы хорошо, однако Rust жалуется:

'cannot move out of borrowed content'

Для функции 'get', где мы пытаемся получить доступ к элементу в векторе.

Что я здесь не так делаю?

1 Ответ

2 голосов
/ 05 апреля 2019

Проблема здесь в том, что Vec владеет Item s, которые он содержит, но Context.get пытается вернуть Item напрямую (и получить его в собственность).

Если Context.get нужно просто позволить вызывающим взглянуть на содержимое вектора, он должен возвратить ссылку на Item вместо Item:

impl Context {
    fn get(&mut self, at: usize) -> &Item {
        &self.x[at]
    }
}

В приведенном выше случае Context.get может принятьнеизменная ссылка на self, поскольку она ничего не меняет.Кроме того, если вы хотите, чтобы вызывающие абоненты Context.get могли изменять указанный элемент, вы бы вернули &mut Item вместо &Item:

impl Context {
    fn get(&mut self, at: usize) -> &mut Item {
        &mut self.x[at]
    }
}

Редактировать: как @apemanzilla любезно отмечает в комментариях,вы также можете сделать так, чтобы Item реализовал черту Clone, если вы хотите, чтобы Context.get возвращал отдельную копию элемента в at:

#[derive(Clone)]
struct Item {
    value: String,
}

impl Context {
    fn get(&mut self, at: usize) -> Item {
        self.x[at].clone()
    }

Изменение возвращенного элемента не изменит тот, который содержится вself.x хотя;это может или не может быть то, что вы хотели.

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