【问题标题】:A simple test case to check my understanding of rust lifetimes一个简单的测试用例来检查我对生锈寿命的理解
【发布时间】:2021-08-25 17:11:56
【问题描述】:

刚看完生锈书chapter on lifetimes

一切都说得通,特别是主要示例之一是以下内容无法编译

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

fn main() {
    let string1 = String::from("long string is long");
    let result;
    {
        let string2 = String::from("xyz");
        result = longest(string1.as_str(), string2.as_str());
    }
    println!("The longest string is {}", result);
}

这是因为“我们告诉 Rust,最长函数返回的引用的生命周期与传入的引用的较小生命周期相同。因此,借用检查器不允许清单 10 中的代码 - 24 可能有一个无效的参考。”而在本章的另一部分“最长函数返回的引用的生命周期与传入的引用的生命周期中的较小者相同。”

所以我很自然地尝试想出我自己的简化示例,如下所示

fn foo<'a>(x: &'a str) -> &'a str {                                                
    x                                                                              
}                                                                                  
                                                                                   
fn main() {                                                                        
                                                                                   
    let y;                                                                         
    {                                                                              
        let x = "hello";                                                           
        y = foo(x);                                                                
    }                                                                              
    println!("y: {}", y);                                                          
}  

令我惊讶的是,它编译并运行得很好。如何?当x 超出范围时,引用y 的生命周期不应该结束吗?

【问题讨论】:

标签: rust lifetime


【解决方案1】:

之所以有效,是因为"hello" 具有静态生命周期,x 只是对该静态字符串的引用。 x 本身超出范围是可以的,它引用的资源具有静态生命周期,因此对于 y 来说足够长。

如果我们改为让x 指向std::String,我们会得到您所期望的错误:

fn foo<'a>(x: &'a str) -> &'a str {                                                
    x                                                                              
}                                                                                  
                                                                                   
fn main() {                                                                        
                                                                                   
    let y;                                                                         
    {                                                                              
        let x = String::from("hello");                                                           
        y = foo(&x);                                                                
    }                                                                              
    println!("y: {}", y);                                                          
}  
error[E0597]: `x` does not live long enough
  --> src/main.rs:10:17
   |
10 |         y = foo(&x);                                                                
   |                 ^^ borrowed value does not live long enough
11 |     }                                                                              
   |     - `x` dropped here while still borrowed
12 |     println!("y: {}", y);                                                          
   |                       - borrow later used here

【讨论】:

    猜你喜欢
    • 2014-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多