Skip to content

更清晰的lifetime描述 #1592

@xingty

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被释放了,调用者还在使用的情况)

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