Rust 引用变量的生命周期,编译器的借用检查器确保你的代码安全可靠

Rust lifetime

Borrow Checker 借用检查器

代码块

Rust编译器会在编译的时候比较作用域变量的生命周期。 Rust官方文档中有如下示例:

{
    let r;                // ---------+-- 'a
                          //          |
    {                     //          |
        let x = 5;        // -+-- 'b  |
        r = &x;           //  |       |
    }                     // -+       |
                          //          |
    println!("r: {}", r); //          |
}

从中我们可以看出,里面括号里的代码块,变量x的作用域局限在里面的括号里,所以它的生命周期明显只有在这个括号里,对比变量r,r的生命周期要比x长,这个时候又将x的引用赋值给r,编译器会报错,因为后面的println!("r: {}", r);打印的r,其实是x。

在函数中分配生命周期

函数传参数,参数为引用,为什么要传引用呢?不想让函数拥有参数的所有权。

&i32                // 这是一个引用
&'a i32             // 这是一个有着详细生命周期的引用
&'a mut i32         // 这是一个有着详细生命周期的可变引用

fn longest<'a>(x: &'a str, y: &str) -> &'a str {
    x
}

// 错误案例
fn longest<'a>(x: &str, y: &str) -> &'a str {
    let result = String::from("really long string");
    result.as_str()
}

为什么的个函数longest会报错呢?原因是result的生命周期要比'a短。

在结构体定义里标记生命周期

哪些规则不需要为引用声明生命周期(lifetime elision rules)生命周期省略

每一个引用都有一个生命周期

在函数或者方法参数中,生命周期被称作输入生命周期,相反,返回值的被称作输出生命周期。

生命周期省略规则

第一条适用于输入生命周期,后面两条则适用于输出生命周期。适用于fnimpl块。 只有满足如下三点,就可以不用声明生命周期。

  1. 每一个引用参数都有自己的一个生命周期。
  2. 如果只有一个输入生命周期参数,那么它被赋予所有输出生命周期参数。
  3. 多个输入生命周期参数,&self&mult self,self的生命周期被赋给所有输出生命周期参数。

0 comments

To reply to the article, please Login or registered