Rust 生命周期

生命周期

避免悬垂引用。

rust可以提前声明,即声明一个变量但不初始化,因为没有赋值,所以也用不了,rust也不存在空值。

借用检查器

比较作用域来判断所有的借用是否合法。被引用的数据存活时间,必须比引用者的长。

函数中的泛型生命周期

手动设置生命周期,当函数返回一个引用的时候,它不会知道这个引用的生命周期,所以要手动设置。

fn main(){
    let account = String::from("achu");
    let result = checkLife(account.as_str(), "xyz");
}

fn checkLife<'a>(x: &'a str, y: &'a str) -> &'a str{
    // 声明作用域生命周期'a
    if x.len() > y.len(){
        x
    } else {
        y
    }
}

上面那个函数的签名的意思:这个函数有个声明周期'a,两个参数的生命周期必须大于'a,函数返回的切片的生命周期也不能短于'a。这并没有改变生命周期,只是增加了约束。

这个'a的作用域是x作用域和y作用域中最短的那一部分。

生命周期的标注语法

  • 生命周期的标准不会改变引用的生命周期长度。
  • 当指定了泛型的生命周期,函数可以接收带有任何生命周期的引用。
  • 生命周期的标准描述了多个引用生命周期间的关系,但不影响声明周期。

以'开头,全小写非常短,一般用'a

放在引用的&符号后面,用空格分开。

&i32
一个引用。

&'a i32
带有显式生命周期的引用。

&'a mut i32
带有显式生命周期的可变引用。

单个生命周期标准本身没有意义。

函数中声明
fn longest<'a>

深入理解生命周期

如果函数只返回一个参数,那么只需要规定返回参数的生命周期就行。

  • 从函数返回引用时,返回的类型的生命周期参数需要与其中一个参数的生命周期相匹配。
  • 如果返回的引用没有指向任何参数。那么它只能引用函数内创建的值:垂悬引用。解决方法是不返回引用,直接返回值。

生命周期在:

  • 函数/方法的参数:输入生命周期。
  • 函数/方法的返回值:输出生命周期。

Struct定义中的生命周期和标注

struct里可以包括

  • 自持有的类型。
  • 引用:需要在每个引用上添加生命周期标注。

struct test<'a>{part: &'a str,}

方法中生命周期标注

需要在struct上使用。

struct test<'a>{part: &'a str}

impl<'a> test<'a> {
  fn level(&self) -> i32{
    3
  }
}

生命周期省略的三个规则。

  1. 每个引用类型的参数都有自己的生命周期。
  2. 如果只有1个输入生命周期参数,那么该生命周期被赋给所有的输出生命周期参数。
  3. 如果有多个输入生命周期参数,但其中一个是&self或&mut self (结构体内的方法),那么self的生命周期会被赋给所有的输出生命周期参数。

静态生命周期 'static

'static 是一个特殊的生命周期:整个程序的持续时间。比如&str

总结

  1. 必须是多个引用。
  2. 函数返回值的生命周期取的是参数中最短的那个生命周期。
  3. &str 字符串字面值是一个静态生命周期,是全局作用域有效存活。
    3.1 &str是直接在可执行文件中执行的,这块内存直接放到可执行文件的,所以不会因为所有权而消失。因此指向这块内存的引用,一直是一个合法的内存。
posted @ 2021-12-02 10:26  阿初  阅读(275)  评论(0编辑  收藏  举报