如何正确注释生命周期

How to properly annotate lifetimes

我一直在努力了解如何在我的应用程序中正确注释生命周期。我已经将实际代码简化为:

struct Item<'a> {
    rf: &'a i32,
}

impl<'a> Item<'a> {
    fn new(main: &'a App) -> Item<'a> {
        Item{
            rf: &main.i
        }
    }
}

struct App<'a> {
    i: i32,
    vec: Vec<Item<'a>>
}

impl<'a> App<'a> {
    fn new() -> App<'a> {
        App {
            i: 32,
            vec: vec![]
        }
    }
    
    fn init(&mut self) {
        self.vec.push(Item::new(self))
    }
    
    fn update(&self) {
        for item in self.vec.iter() {
            println!("{}", item.rf)
        }
    }
}


fn main() {
    let app = App::new();
    app.init();
    app.update();
}

所以有一个包含对应用程序中某些内容的引用的项目向量,我知道只要应用程序存在,它就会存在,但借用检查器不接受这一点。有人可以解释一下这段代码有什么问题以及我该如何解决吗?

你可以在 rust playground 中找到这段代码:https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=ee8980c9e1b2a0622548525dbcf9f50f

我认为问题在于 Rust 如何处理引用并推断它们。这是一个可能的解决方案。

简而言之,我们告诉 Rust 编译器,在 App 结构中,第 i 个成员存在 'a length。然后我们可以与另一个至少存在 'a' 的结构共享这个成员。我们通过在创建它时告诉 Item 结构来实现这一点,它至少必须至少在 App 结构的生命周期内存在。因为编译器可能对推断和匿名生命周期有点挑剔,所以我们必须明确。我们通过在 Item 结构的新方法中添加一个 'b 来做到这一点。然后,当我们使用 app 结构的生命周期 'a 调用此方法时,编译器知道 Item 的生命与 App 一样长。抱歉,这里的解释比我可能知道的要多。

struct Item<'a> {
    rf: &'a i32,
}

impl<'a> Item<'a> {
    fn new<'b>(main: &'b App<'a>) -> Item<'a> {
        Item{
            rf: main.i
        }
    }
}

struct App<'a> {
    i: &'a i32,
    vec: Vec<Item<'a>>
}

impl<'a> App<'a> {
    fn new() -> App<'a> {
        App {
            i: &32,
            vec: vec![]
        }
    }
    
    fn init(&mut self) {
        let item = Item::new(self);
        self.vec.push(item)
    }
    
    fn update(&self) {
        for item in self.vec.iter() {
            println!("{}", item.rf)
        }
    }
}


fn main() {
    let mut app = App::new();
    app.init();
    app.update();
}