rust - Rust 中的生命周期 : mut data borrowed

标签 rust lifetime

以下代码报错: 借用的值(value)生命周期不够长

fn main() {
    let e = 100;
    let mut a = (1,);
    let mut b = (&e,);
    {
        let mut c = (&mut a, &mut b);
        let f = &mut c;
        f.1 .0 = &(f.0 .0);
    }
    println!("{:?}", b);
}

但是下面的代码是正确的:


fn main() {
    let e = 100;
    let a = (1,);
    let mut b = (&e,);
    {
        let mut c = (&a, &mut b);
        let f = &mut c;
        f.1 .0 = &(f.0 .0);
    }
    println!("{:?}", b);
}

为什么?!!

第一个代码的完整错误消息:

error[E0597]: `c` does not live long enough
  --> src/main.rs:7:17
   |
6  |         let mut c = (&mut a, &mut b);
   |             ----- binding `c` declared here
7  |         let f = &mut c;
   |                 ^^^^^^ borrowed value does not live long enough
8  |         f.1 .0 = &f.0 .0;
9  |     }
   |     - `c` dropped here while still borrowed
10 |     println!("{:?}", b);
   |                      - borrow later used here

For more information about this error, try `rustc --explain E0597`.

最佳答案

这是因为共享引用是复制,而可变引用则不是。

这是代码的精简版本,更容易讨论:

fn main() {
    let mut a = 1;
    let b;
    {
        let mut c = &mut a;
        // Or:
        let mut c = &a;
        let f = &mut c;
        b = &**f;
    }
    println!("{b}");
}

让我们分别将 ac 的生命周期称为 'a'c。因此,f 的类型为 &'c mut &'a [mut] i32。当我们执行 b = &**f 时,可变版本和不可变版本之间存在差异。

在不可变版本中,我们取消引用f以获取&'a i32。然后我们复制这个引用(这很好,因为共享引用是复制),并获得一个&'a i32类型的独立引用。我们可以将此引用(或其重新借用的版本 &*r)分配给 b,因为 a 具有相同的范围 b 有。

在可变的情况下,我们还取消引用f。然而,我们得到的引用是一个可变引用:&'a mut i32。由于可变引用不是Copy,因此我们无法将其复制为独立引用。它必须留在原处,位于 f&'c mut 后面。

但是,我们可以做的是重新借用该引用来创建一个源自它的引用。然而,当你重借&'a mut &'b mut T类型的引用时,你无法得到&'b mut T类型的引用,只能得到 &'a mut T。否则,您获得的引用可能会比原始引用更长久,并且在您没有此类引用的权限时仍然存在。

因此,我们得到 &'c mut i32,而不是 &'a mut i32b 的生命周期比 c 长,因此我们无法分配 &'c mut i32 (或共享的 &'c i32从它创建)到b

关于rust - Rust 中的生命周期 : mut data borrowed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76323931/

相关文章:

rust - 有效地对向量进行变异,同时在相同的向量上进行迭代

rust - 我正在安装 “parquet-schema: command not found”,尽管我已经完成了 cargo 安装拼花地板

reference - 如何在引用的 Vec 上使用生命周期?

module - 从 Rust 中同一类的另一个静态方法引用静态方法的最佳方法是什么?

enums - 我可以使用枚举作为另一个枚举的值检查器吗?

rust - 如何在 Hyper 处理程序之间共享 HashMap?

rust - 可变引用的再借用

generics - 在Rust中编写一个将可迭代容器作为参数的泛型函数

closures - 通用 fn、 channel 和线程生成

rust - 超性状范围内的生命周期参数