首页 > 解决方案 > 为什么 Rust 中作为参数传递的 &str 数组具有不同的生命周期?

问题描述

我正在学习 Rust 并且正在通过函数测试一些数组复制。我确信有内置的 Rust 函数来复制/克隆数组信息,但我认为个人实现将是一个好主意,可以帮助我理解通过函数传递引用。

fn copy_str_arr_original (a1: [&str; 60], a2: &mut [&str; 60]) {
    // copy 1 into 2
    for i in 0..60 {
        a2[i] = a1[i];
    } // change is reflected in a2 as it is passed as &mut
}

但是,这引发了these two types are declared with different lifetimes...类型&str本身的错误。经过一些进一步的研究,我尝试宣布自己的生命并将其分配给它,并且解决了它!

fn copy_str_arr_fix<'a> (a1: [&'a str; 60], a2: &mut [&'a str; 60]) {
    // copy 1 into 2
    for i in 0..60 {
        a2[i] = a1[i];
    } // change is reflected in a2 as it is passed as &mut
}

为什么会这样呢?为什么需要为数组中的值类型而不是参数本身分配生命周期?换句话说,为什么这根本不起作用?

fn copy_str_arr_bad<'a> (a1: &'a [&str; 60], a2: &'a mut [&str; 60]) {
    // does not work...           ^-----------------------^-------- different lifetimes
    for i in 0..60 {
        a2[i] = a1[i]; 
    } 
}

我仍在努力了解生命周期如何在更复杂的对象(如数组和结构)的上下文中工作,所以任何解释都将不胜感激!

标签: arraysfunctionrustlifetime

解决方案


错误消息有点令人困惑,因为它指的是根据生命周期省略规则生成的生命周期。在您的情况下,终身省略意味着:

fn copy_str_arr_original(a1: [&str; 60], a2: &mut [&str; 60])

是语法糖:

fn copy_str_arr_original<'a1, 'a2_mut, 'a2>(a1: [&'a1 str; 60], a2: &'a2_mut mut [&'a2 str; 60])

换句话说,我们有三个完全不相关的生命周期。“不相关”意味着调用者可以选择与它们关联的对象的生存时间。例如,in 中的字符串a2可能是静态的并且一直存在到程序结束,而 in 中的字符串可能在返回a1后立即被删除。copy_str_arr_original()或者反过来。如果这种自由度看起来可能会导致问题,那么您就在正确的轨道上,因为借用检查器同意您的看法。

请注意,有点违反直觉,'a2_mut生命周期的长度完全无关紧要,它可以与调用者一样长或短。我们的函数已收到引用,因此可以在函数范围内使用它。'a2_mut生命周期告诉我们它将在函数范围之外存在多长时间,我们只是不关心这一点。

'a1'a2是另一回事。由于我们从a1to复制引用a2,因此我们有效地将(类型)内部的引用转换为存储在(即)中的引用类型:a1&'a1 stra2&'a2 str

a2[i] = a1[i];  // implicitly casts &'a1 str to &'a2 str

要使其有效,&'a1 str必须是 的子类型&'a2 str虽然 Rust 没有 C++ 意义上的类和子类,但它确实有涉及生命周期的子类型。从这个意义上说,如果 A 值的值保证至少与 B 的值一样长,则 A 是 B 的子类型。换句话说,'a1必须至少与 一样长'a2,表示为'a1: 'a2。所以编译:

fn copy_str_arr<'a1: 'a2, 'a2, 'a2_mut>(a1: [&'a1 str; 60], a2: &'a2_mut mut [&'a2 str; 60]) {
    for i in 0..60 {
        a2[i] = a1[i];
    }
}

演员表成功的另一种方法是只要求生命周期与copy_str_arr_fix(). (您还省略了'a2_mut生命周期,编译器将其正确解释为对不相关的匿名生命周期的请求。)


推荐阅读