Где происходит проблемный заем? - PullRequest
0 голосов
/ 14 декабря 2018
pub struct Dest<'a> {
    pub data: Option<&'a i32>,
}

pub struct Src<'a> {
    pub data: Option<&'a i32>,
}

pub trait Flowable<'a: 'b, 'b> {
    fn flow(&'a self, dest: &mut Dest<'b>);
}

impl<'a: 'b, 'b> Flowable<'a, 'b> for Src<'a> {
    fn flow(&self, dest: &mut Dest<'b>) {
        dest.data = self.data;
    }
}

struct ContTrait<'a, 'b> {
    pub list: Vec<Box<Flowable<'a, 'b> + 'a>>,
}

impl<'a: 'b, 'b> Flowable<'a, 'b> for ContTrait<'a, 'b> {
    fn flow(&'a self, dest: &mut Dest<'b>) {
        for flowable in self.list.iter() {
            flowable.flow(dest);
        }
    }
}

fn main() {
    let x1 = 15;
    let x2 = 20;
    let mut c = ContTrait { list: Vec::new() };

    let mut dest = Dest { data: Some(&x2) };
    c.list.push(Box::new(Src { data: Some(&x1) }));
    c.flow(&mut dest);
}

Я пытаюсь реализовать передачу ссылки из одной структуры в другую структуру.Каждый раз, когда я немного прогрессирую, будет новый блок.То, чего я хочу достичь, выглядит тривиально в языке, подобном C ++, для типа Src определена черта Flowable, если определенное условие выполнено, ссылка в A будет передана типу Dest.Я играл некоторое время со спецификатором жизни, чтобы сделать компилятор Rust счастливым.Теперь я также реализую ту же черту для типа ContTrait, который является коллекцией Flowable, и эта ContTrait также реализует черту Flowable для итерации каждого объекта в нем и вызова потока.Это упрощенный случай для реального использования.

Я просто не могу понять, почему компилятор Rust сообщает

error[E0597]: `c` does not live long enough
  --> src\main.rs:38:5
   |
38 |   c.flow(&mut dest);
   |   ^ borrowed value does not live long enough
39 | }
   | -
   | |
   | `c` dropped here while still borrowed
   | borrow might be used here, when `c` is dropped and runs the destructor for type `ContTrait<'_, '_>

1 Ответ

0 голосов
/ 14 декабря 2018
pub trait Flowable<'a: 'b, 'b> {
    fn flow(&'a self, dest: &mut Dest<'b>);
}

В основе проблемы лежит &'a self.Это говорит о том, что объект flow вызывается должен пережить время жизни dest параметризован с.

В main, вы делаете

c.flow(&mut dest);

и dest неявнопараметризован с временем жизни x2.Так как вы звоните flow на c, вы подразумеваете, что c должен пережить x2, а это не так.

Если вы удалите 'a, связанный с собственной ссылкой в ​​чертеопределение и ContTrait impl, код компилируется.

...