• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Rust生命周期标注lifetime annotation

武飞扬头像
某科学的泡泡茶壶
帮助1

Rust语言中的所有引用(referrence)都有一个lifetime,指得是该引用有效的作用域(scope)。通常情况下,lifetime都是隐式的,rust编译器会根据一些简单的规则自己推断。但在一些复杂情况下,编译器无法准确的判断引用的生命周期,则需要我们手动标注lifetime。

比如写一个返回最长字符串的函数,像下面这么写就通不过编译。因为函数返回值也是引用,但又因为我们有两个引用作为输入参数,而rust在编译的时候不知道返回谁,也就无法确认函数返回值的生命周期。

  1.  
    fn longest(x: &str, y: &str) -> &str {
  2.  
    if x.len() > y.len() {
  3.  
    x
  4.  
    } else {
  5.  
    y
  6.  
    }
  7.  
    }
  1.  
    error[E0106]: missing lifetime specifier
  2.  
    --> src/main.rs:1:33
  3.  
    |
  4.  
    1 | fn longest(x: &str, y: &str) -> &str {
  5.  
    | ^ expected lifetime parameter
  6.  
    |
  7.  
    = help: this function's return type contains a borrowed value, but the
  8.  
    signature does not say whether it is borrowed from `x` or `y`

生命周期标注

生命周期标注就是为了在上面这种情况下告诉Rust编译器,函数返回值的生命周期是怎么样的。生命周期的标注语法如下,一个生命周期变量可以用‘ 一个或几个小写字母表示(比如 ‘a ’abc),生命周期变量放在引用符号 & 与引用名称之前。

  1.  
    &i32 // a reference
  2.  
    &'a i32 // a reference with an explicit lifetime
  3.  
    &'a mut i32 // a mutable reference with an explicit lifetime

用生命周期标注改写上述函数 

  1.  
    fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
  2.  
    if x.len() > y.len() {
  3.  
    x
  4.  
    } else {
  5.  
    y
  6.  
    }
  7.  
    }

上面的代码里,我们用一个生命周期变量‘a (其实你可以认为这是一种标签)同时标注了两个参数以及返回值,来告诉Rust编译器这三者的生命周期是一样的。虽然这不一定是对的,因为这两个输入参数的生命周期实际上有可能是不一样的,但是可以让Rust编译器暂时这么理解。因为标注的重点其实在于,告诉Rust编译器你可以用x或者y的生命周期来当作函数返回值的生命周期。

因为x和y的生命周期有可能不一样,所以函数返回值的生命周期实际上是由两个参数里生命周期较短的那个决定的。

  1.  
    fn main() {
  2.  
    let string1 = String::from("long string is long");
  3.  
    let result;
  4.  
    {
  5.  
    let string2 = String::from("xyz");
  6.  
    result = longest(string1.as_str(), string2.as_str());
  7.  
    } // 1
  8.  
    println!("The longest string is {}", result); //2
  9.  
    }
  1.  
    error[E0597]: `string2` does not live long enough
  2.  
    --> src/main.rs:15:5
  3.  
    |
  4.  
    14 | result = longest(string1.as_str(), string2.as_str());
  5.  
    | ------- borrow occurs here
  6.  
    15 | }
  7.  
    | ^ `string2` dropped here while still borrowed
  8.  
    16 | println!("The longest string is {}", result);
  9.  
    17 | }
  10.  
    | - borrowed value needs to live until here

上述代码里,函数返回值result的生命周期就由生命周期较短的string2决定。由于string2的生命周期在1处已经结束了,所以2处不可以在使用result这一函数返回值。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgcjhgg
系列文章
更多 icon
同类精品
更多 icon
继续加载