本文仅作笔记不作教程,仅作学习笔记 有任何错误请指出,部分参考自 rust圣经
每个引用都有生命周期 存在的目的: 避免悬垂引用
A 引用 B, 则必须保证 B的生命周期是大于A 注意这句话 后面是一直围绕着这句话展开
一個函數要返回的東西 其生命周期要確定 , 如 在if-else 中返回的兩個東西生命周期不同 既是不確定的狀態要用<'a> 來標注
對於單個變量 沒有什麽作用,一般用於汎型作用于多個引用 来告诉编译器两个泛型之间生命周期的联系
|
|
而且此處標注并不會改變任何變量的生命周期 它的作用就是一個注解告訴borrow checker 拿到最小的生命周期
|
|
對於上述代碼 result 它所拿到的生命周期為<'a>
而 <'a> 是 string1 與string2交集當中最小的那個 string2
观察上面代码发现 result【拿到】的生命周期 ==等于== <‘a> 但是 显然 result这个变量的生命周期变量是大于 <`a> 的 所以 明显不符。
那么只有让 result 的生命周期 等于 <`a> 也就是二者之间较小的那个就可以编译通过
|
|
简而言之 这个规则就保证了 你不能用长的生命周期 来引用一个短的生命周期,只能用生命周期短的来引用比你生命周期长的
生命周期的三个规则
-
每个引用都会有自己的生命周期
-
若函数参数只有一个引用类型,那么该生命周期会被赋予给所有输出的生命周期 也就是所有返回值的生命周期都等于该输入生命周期
例如函数
fn foo(x: &i32) -> &i32,x参数的生命周期会被自动赋给返回值&i32,因此该函数等同于fn foo<'a>(x: &'a i32) -> &'a i32 -
若存在多个输入生命周期,且其中一个是
&self或&mut self,则&self的生命周期 默认被赋给所有的输出生命周期
结构体的生命周期
每个引用都有自己的生命周期, 那么如果在结构体里面有一个引用 那么编译器并不知道结构体 和 结构体里面的引用谁存活更久
所以要为结构体标明标识符
|
|
而对于这个标识符<'a> 实际上 二者生命周期的交集,
假设part活得久,那么在创建的struct的时候是可以有效引用
而假设 struct 活得久,就相当于是 用一个长生命周期的东西来引用 一个短生命周期的东西 就造成了悬垂引用 也就是上面的举例。
所以如果在struct里面有引用 一定要保证里面的引用都是比struct活得久 否则编译不会过
如果还不理解 看本文的第一句话。
方法的生命周期
运用第一和第三规则展开 这里不多做解释
由于编译器不知道 第二个参数 announcement 的生命周期到底为多长 所以会加上<'b>
|
|
还是做一个分析 这里的生命周期是一个交集 , 既<'a> 和 <'b> 最小的交集
那为什么返回值 为<‘a> 是能够保证有效的呢
因为使用这个方法是在初始化结构后后做的 意味着 你的生命周期是比结构体短, 而短的生命周期是可以使用长的生命周期的东西。
如果我们把返回值的生命周期改为 <'b> 就会报错 因为返回值为self.part 生命周期为<‘a> 编译器并不知道
<'a> 和 <'b>的关系
|
|
在这里显然要保证 <'b> 必须比 <'a> 活得短 否则就会悬垂引用 所以就要使用 类似泛型约束的 生命周期约束 来告诉编译器 二者之间的关系
|
|
这个约束语法<'a:'b> 是告诉编译器 b 必须比 a活得短
不难发现 返回的是 self.part 若不要出现悬垂引用 只能短的生命周期引用长的生命周期,所以 'b 是要比'a 活得短
self.part是结构体里的东西 ,方法返回的是 <'b> 相当于 用 <'b>生命周期的东西引用 <'a> , 意味着 <'b> 必须比<'a>活得短
使用where简化
|
|
静态生命周期
标注'static 遇到错误 不要轻易的使用static魔改.
事实上,关于
'static, 有两种用法:&'static和T: 'static,详细内容请参见此处。