Skip to content

更清晰的lifetime描述 #1592

Description

@xingty

在书中第二章第10小节(对应basic/lifetime.md),有一段描述如下:

在结束这块儿内容之前,再来做一个有趣的修改,将方法返回的生命周期改为'b:

impl<'a> ImportantExcerpt<'a> {
    fn announce_and_return_part<'b>(&'a self, announcement: &'b str) -> &'b str {
        println!("Attention please: {}", announcement);
        self.part
    }
}

此时,编译器会报错,因为编译器无法知道 'a 和 'b 的关系。 &self 生命周期是 'a,那么 self.part 的生命周期也是 'a,但是好巧不巧的是,我们手动为返回值 self.part 标注了生命周期 'b,因此编译器需要知道 'a 和 'b 的关系。

有一点很容易推理出来:由于 &'a self 是被引用的一方,因此引用它的 &'b str 必须要活得比它短,否则会出现悬垂引用。因此说明生命周期 'b 必须要比 'a 小,只要满足了这一点,编译器就不会再报错:

impl<'a: 'b, 'b> ImportantExcerpt<'a> {
    fn announce_and_return_part(&'a self, announcement: &'b str) -> &'b str {
        println!("Attention please: {}", announcement);
        self.part
    }
}

Bang,一个复杂的玩意儿被甩到了你面前,就问怕不怕?

其实作为一个初学者,我在看到这一小段描述是充满困惑的:

有一点很容易推理出来:由于 &'a self 是被引用的一方,因此引用它的 &'b str 必须要活得比它短,否则会出现悬垂引用。因此说明生命周期 'b 必须要比 'a 小,只要满足了这一点,编译器就不会再报错:

后面查了一些资料才理解了这段要表达的含义。我在想是不是可以改成下面这种描述,会减少一些初学者的困惑:

因为announce_and_return_part的函数签名承诺的返回值的生命周期是&'b str,所以&'b str的生命周期必须小于等于&'a str,程序才不会报错(设想一下,如果'b > 'a,函数实际返回了'a,但调用者把这个返回值当成'b使用,那么就会出现'a被释放了,调用者还在使用的情况)

。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions