有问题的借贷发生在哪里?

时间:2018-12-14 10:49:52

标签: rust lifetime borrowing

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 :(得分:4)

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隐含代码,则会编译代码。