【问题标题】:How does Rust calculate lifetime of a moved value?Rust 如何计算移动值的生命周期?
【发布时间】:2022-12-19 14:07:48
【问题描述】:

在 Rust 中,值的生命周期介于定义点和超出范围的点之间。

然而,超出范围可以是声明的结尾抢断价值。

Rust 仅部分尊重这一点。为什么?

举个例子:

// This is the starting point, it compiles without errors/warnings, but does not do what it should.
struct Inner{x : i32}

struct Outer<'e>{
    s : &'e Inner,
    c : i32
}

fn print_inner_value(mut o : Outer) {
    println!("o.s.x = {:?}", o.s.x);
    o.c += 1;
}

fn change_inner(mut o : Outer) {
    let new_i = Inner{x : 40};
    o.c += 2;
    //o.s = &new_i;
    print_inner_value(o);
    println!("new_i.x = {:?}", new_i.x);
    //o.c += 3;
}

fn main () {
    let orinal_i = Inner {x : 10};
    let mut o = Outer{s : &orinal_i, c : 0};
    o.c += 4;
    change_inner(o);
}

我真正想要的是o.s = &amp;new_i; 行不被评论。

但如果我这样做,我会得到 E0597 说 new_i 的寿命不够长。

但它似乎活得足够长,因为如果我改为取消注释 o.c += 3; 然后我得到 E0382 说 o.c 不能使用,因为它已被移动。

很明显,在println!("new_i.x = {:?}", new_i.x); 行,值new_i 处于活动状态,而值o 已移至已结束的函数中,因此它不应再处于活动状态。

所以问题是:为什么移动一个值会缩小它的范围,但不会缩短它的生命周期?

【问题讨论】:

  • 可以允许此特定代码。但是你可以重新绑定o使其编译。

标签: rust lifetime borrow


【解决方案1】:

您的错误是假设'e 的生命周期代表Outer 的生命周期:它不是。

相反,由于 Outer&lt;'e&gt; 类型的值 o 包含生命周期为 'e 的引用,因此此值 o 的生命周期必须短于(或等于)'e —— 以免值 @ 987654328@ 比所引用的元素寿命更长,并以悬空引用结束。


你遇到的真正问题是不变性来自'e

当您在main 中创建实例o 时,生命周期'e 的计算结果与orinal_i 的生命周期相匹配。

然后,在 change_inner 内,当您着手更改 o.s 时,类型系统要求您分配的任何引用的生命周期必须大于或等于这个预定的 'e,即大于或等于orinal_i

价值o 的,包含所述引用,将很快消失,对所需的生命周期没有影响。


另一种看待它的方式是o的范围对orinal_i被借用多长时间有影响,但不影响orinal_i的生命周期:无论o活得短还是长,它都不会改变orinal_i的生命周期有多长,o访问orinal_i的时间有多长。

【讨论】:

    猜你喜欢
    • 2013-07-03
    • 2021-05-31
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    • 2015-09-24
    • 1970-01-01
    • 1970-01-01
    • 2014-09-10
    相关资源
    最近更新 更多