9. Rust 函数参数上的生命周期(lifetime)标记
上一条:C++ 生命周期回顾 下一条:结构体成员的生命周期(lifetime)标记
(1)首先,Rust的编译器需要明确地知道一个借用对象是否还是有效的。例如返回一个新创建的对象肯定是有效的,不需要检查。
fn create_obj():Object{
Object{}
}
(2)但是,显然你不能返回一个局部对象的借用,因为局部对象在函数结束后超出作用域就被释放了:
fn get_obj():&Object{ // compile error
const obj = Object{};
&obj
}
(3)不过,如果这个借用本来就是从外部传入的,那当然可以返回,函数结束后这个对象还是有效的:
// I am borrowed from caller
// return borrow to the caller is safe
fn process_obj(obj:&Object):&Object{
&obj
}
(4)然而,如果你传入了两个对象的借用,内部做了条件返回。那么编译器没那么智能,它并不总是能推断出返回的是哪个对象的借用:
// compile error!
// where am I come from?
fn process_objs(x:&Obejct, y:&Object):&Object{
if(x.is_ok()){
&x
}else{
&y
}
}
(5)因此,Rust保留了内部的一种编译器内部的,本来是隐式添加记号,也就是生命周期(lifetime),通过显式添加生命周期标记,解决上述问题:
// I am come from 'a lifetime, NOT 'b
fn process_objs<'a,'b>(x: &'a Obejct, y:&'b Object):&'a Object{
&x
}
// I am come from 'a lifetime, x,y,and result are all 'a lifetime
fn process_objs<'a>(x: &'a Obejct, y:&'a Object):&'a Object{
if(x.is_ok()){
&x
}else{
&y
}
}
(6)事实上,当你没写lifetime标记时,每个对象也都是有对应的lifetime的,例如编译器为每个对象生成一个不同的lifetime
fn test<'a,'b>(x: &'a Obejct, y:&'b Object){
}
(7)因为默认生成的都是不同的,所以返回值如果不标记是谁,编译器就无法推断:
fn test<'a,'b,'c>(x: &'a Obejct, y:&'b Object):&'c Object{ // 'c is 'a or 'b ?
if(x.is_ok()){
&x
}else{
&y
}
}
(8)所以如果我们显式标记,并让两个变量用同一个,就能解决,这就是告诉编译器,`'c='a='b`:
fn test<'a>(x: &'a Obejct, y:&'a Object):&'a Object{ // 'c='a='b, they are all 'a
if(x.is_ok()){
&x
}else{
&y
}
}
(9)看到这里,你也应该知道了lifetime标记的名字是任意的,只是一个【形参】,代表的是这个借用对象的生命周期作用域的名字:
{
let obj; //---'a start here
{
let x = Obj{}; //---'b start here
obj = &x; //---'b finish here
}
println!("obj: {}", obj); //---'a finish here, 'b is out of scope, compile error!
}
// #[derive(Apparition)]
{
// 当然你可以用任意合法的符号替换'a和'b,它们只是个名字
let obj<'b>; //---'a start here
{
let x = Obj{}; //---'b start here
obj<'b> = &'b x; //---'b finish here
}
// obj借用是否有效,仅仅取决于它实际上它所借用的对象的生命周期作用域'b范围是否大于等于'a
// 一个'b作用域内的对象的借用,在'a内被调用,但是'b比'a小,调用的时候'b已经不存在了
// 因此编译器宣布:这是非法的。
println!("obj: {}", obj<'b>); //---'a finish here, 'b is out of scope, compile error!
}
相关推荐
rust中文教程
rust中文教程
深入理解 Rust 生命周期(可能是全网最透彻的解读了)
本文通过生动的代码示例和清晰的逻辑分析,深入浅出地讲解了Rust生命周期的核心概念。作者首先以一个悬垂引用的例子引出生命周期标注的必要性,然后系统性地阐述了四条关键规则:引用生命周期不能超过被引用值、生命周期是编译期概念、引用传播生命周期依赖而值会截断依赖、多输入引用时输出引用的生命周期是输入引用的交集。文章特别强调要区分编译期静态分析和运行时动态执行的思维差异,并指出生命周期标注的本质是帮助编译器进行借用检查。通过将抽象概念具象化为伪代码标注,作者为读者提供了理解Rust生命周期的有效"抓手",使这个原本
一文掌握Rust编程中的生命周期.pdf
内容概要:这篇文章深入介绍了在Rust编程中的生命周期概念,强调了在Rust语言中每个引用都有其生命周期,即引用在程序执行过程中具有自身的作用域,一旦超出作用域范围,其生命周期也随之结束,值变得无效。文章通过解释生命周期的概念和重要性,帮助读者更好地理解和应用Rust编程中的引用和生命周期管理。 适用人群:适合对Rust编程语言有一定了解的开发者、学习者以及对系统级编程和内存管理感兴趣的人群。无论是初学者还是有一定Rust编程经验的用户,都可以从本文中深入了解Rust中的生命周期概念及其应用。 使用场景及目标:可用于系统级编程、并发编程、内存安全等场景。通过学习Rust编程中的生命周期概念,读者可以提高对内存管理和引用生命周期的理解,编写更安全、高效的Rust程序,避免内存泄漏和悬空引用等问题。 其他说明:建议读者在阅读文章的同时结合实际代码示例进行练习和实践,加深对Rust生命周期的理解和掌握。生命周期管理是Rust语言的重要特性之一,对于编写高质量、安全的代码至关重要。通过掌握Rust中生命周期的概念和应用,读者可以提升编程技能,编写更可靠的Rust程序。祝愿读者通过本文学习
lifetime-variance-example:工作Rust示例演示差异
Rust的生命周期方差 这个工作示例涵盖了Rust的变异基础,因为它适用于生命周期,以素养的编程风格编写。 这是一个工作的Rust板条箱。 克隆此仓库并运行cargo build以与其一起玩。 转到开始! 执照
Rust的生命周期练习和讲解
本资源主要讲解了Rust的生命周期标注,以及添加生命周期的方法 并介绍&' static生命周期的使用方法 并介绍Rust的生命周期如何在Trait Bound上使用



