Почему структурное поле занято дольше, чем ожидалось - PullRequest
0 голосов
/ 02 марта 2020

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

struct Element<'a> {
    previous: Vec<&'a Element<'a>>,
}

struct Container<'a> {
    elements: Vec<Element<'a>>,
}

impl <'a>Container<'a> {
    fn new() -> Container<'a> {
        Container{elements: Vec::new()}
    }

    fn add(&'a mut self) -> &'a Element {
        let previous = self.elements.iter().collect();
        let element = Element{previous: previous};
        self.elements.push(element);
        &self.elements[self.elements.len() - 1]
    }
}

fn main() {
    let mut _c = Container::new();
}

Это происходит с ошибкой

error[E0502]: cannot borrow `self.elements` as mutable because it is also borrowed as immutable
  --> nested.rs:17:9
   |
9  | impl <'a>Container<'a> {
   |       -- lifetime `'a` defined here
...
15 |         let previous = self.elements.iter().collect();
   |                        --------------------
   |                        |
   |                        immutable borrow occurs here
   |                        argument requires that `self.elements` is borrowed for `'a`
16 |         let element = Element{previous: previous};
17 |         self.elements.push(element);
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0502`.

Но почему заимствованы self.elements для 'a? Я ожидал бы, что это больше не будет заимствовано после того, как collect() сделан. Я ожидаю, что каждый элемент, который был в self.elements, будет заимствован неизменно, потому что его ссылки теперь хранятся в element.previous. Но self.elements должен быть свободен, чтобы быть мутированным сейчас.

1 Ответ

0 голосов
/ 02 марта 2020

Ошибка: невозможно заимствовать self.elements как изменяемый, потому что он также заимствован как неизменный

// this is borrow self.selements
let previous:Vec<&Element> = self.elements.iter().collect();

previous заимствован из self.elements как неизменяемый,

self.elements.push(element); use self.elements как изменяемый, вы не можете использовать изменяемые и неизменяемые оба

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