1,725
社区成员
发帖
与我相关
我的任务
分享
首条:Rust 所有权(Ownership) 上一条:结构体成员的生命周期(lifetime)标记(lifetime)标记 下一条:未完待续
结构体成员函数和普通函数一样,可以有生命周期标识
struct Range{
start: usize,
len: usize
}
impl Range{
// 接受一个外部的Vec对象的借用作为参数
// 返回这个Vec的片段的一个借用
// 因此,需要引入生命周期标识
// 表明返回的&[u8]的生命周期和传入的owner的生命周期一致
pub fn as_slice<'a>(&self, owner: &'a Vec<u8>)->&'a [u8] {
let slice = &owner[self.start..self.end()];
slice
}
}
下面的代码会出错:
enum AdvancedPiece{
Range(Range),
Vec(Vec<u8>)
}
impl AdvancedPiece{
pub fn as_slice<'a>(&self, owner: & 'a Vec<u8>)->&'a [u8] {
match self {
AdvancedPiece::Range(range)=>{
// range.as_slice(owner)返回的&[u8]生命周期和owner一致,用'a标记
range.as_slice(owner)
},
AdvancedPiece::Vec(vec)=> {
// compile error: &vec的生命周期和owner并不一致
&vec
}
}
}
}
结构体生命周期标识的一个需要注意的地方是,&self也是可以标注生命周期的,因为&self本身也是一个借用,既然是借用,就可以标记生命周期。从这个角度也可以进一步理解,生命周期就是标记借用对象的存活作用域用的。上述代码,实际上等价于:
enum AdvancedPiece{
Range(Range),
Vec(Vec<u8>)
}
impl AdvancedPiece{
// self有自己独立的生命周期,用独立的生命周期标识'b 标记出来
// 这样就看得更清楚了
pub fn as_slice<'a,'b>(&'b self, owner: & 'a Vec<u8>)->&'a [u8] {
match self {
AdvancedPiece::Range(range)=>{
// range.as_slice(owner)返回的&[u8]生命周期和owner一致,用'a标记
range.as_slice(owner)
},
AdvancedPiece::Vec(vec)=> {
// compile error: &vec的生命周期是'b , 返回值需要的是'a
&vec
}
}
}
}
因此,我们可以标记&self和owner的生命周期是一致的来向编译器说明需求:
enum AdvancedPiece{
Range(Range),
Vec(Vec<u8>)
}
impl AdvancedPiece{
// 约定调用as_slice在self和owner的生命周期交集'a内是合法的
pub fn as_slice<'a>(&'a self, owner: & 'a Vec<u8>)->&'a [u8] {
match self {
AdvancedPiece::Range(range)=>{
// range.as_slice(owner)返回的&[u8]生命周期和owner一致,用'a标记
range.as_slice(owner)
},
AdvancedPiece::Vec(vec)=> {
&vec // 此时,&vec的生命周期也是'a
}
}
}
}