Rust 是否会缩短生命周期以满足对它们定义的约束?

问题描述

请考虑这个例子 (playground):

struct Container<'short,'long: 'short,T: 'long> {
    short_prop: &'short u8,long_prop: &'long T,}

fn main() {
    let value = 9;
    let long = &value;

    {
        let short = &value;
        let res = Container {
            short_prop: long,long_prop: short,// why is this not an error?
        };

        println!("{} {}",res.short_prop,res.long_prop);
    }
}

Container 中,我指定了 'long: 'short,我假设意味着 'long 应该至少与 'short 一样长。在 main 中,变量 long 应该比 short 存活时间更长,因为它的作用域更大。

所以 Container 期望进入 long_prop 的任何东西至少与进入 short_prop 的任何东西一样长。然而,编译器对我将寿命较长的 long 传递到 short_prop 并将寿命较短的 short 传递到 long_prop 非常满意。

这是因为在实例化 Container 时,编译器将 long 的生命周期缩小为等于 short 的生命周期,从而满足 'long: 'short 约束(因为相等一生都很好)?还是另有原因?

解决方法

这是因为在 Container 的实例化时,编译器将 'long 的生命周期缩小为等于 'short 的生命周期,从而满足 'long: 'short 约束(因为相等一生都很好)?

是的。

还是有其他原因?

没有。

这是一个使用更简单的 Container 结构的示例,它一次只保存 1 个引用。它可以同时保存 longshort 引用的原因是因为较长的生命周期是较短的子类型,但是 container 变量的整体生命周期被缩小到这两者的最小重叠生命周期,这意味着 containershort 同时超出范围:

#[derive(Debug)]
struct Container<'a> {
    some_ref: &'a str
}

fn main() {
    let long = String::from("long");
    let long_ref = &long;
    
    let mut container = Container {
        some_ref: long_ref,};
    
    dbg!(&container);

    {
        let short = String::from("short");
        let short_ref = &short;

        container.some_ref = short_ref;

        dbg!(&container);
    } // both short & container go out of scope here
    
    dbg!(&container); // error,container dropped in block above,has same lifetime as short
}

playground