Rust 为什么链接生存期只与可变引用有关?

Rust 为什么链接生存期只与可变引用有关?,rust,reference,covariance,lifetime,Rust,Reference,Covariance,Lifetime,几天前,有人对包含借用数据本身的类型的可变引用的链接生存期有问题。问题在于提供对该类型的引用时,其借用的生存期与该类型内借用的数据相同。 我试图重现这个问题: struct VecRef<'a>(&'a Vec<u8>); struct VecRefRef<'a>(&'a mut VecRef<'a>); fn main() { let v = vec![8u8, 9, 10]; let mut ref_v =

几天前,有人对包含借用数据本身的类型的可变引用的链接生存期有问题。问题在于提供对该类型的引用时,其借用的生存期与该类型内借用的数据相同。 我试图重现这个问题:

struct VecRef<'a>(&'a Vec<u8>);

struct VecRefRef<'a>(&'a mut VecRef<'a>);

fn main() {
    let v = vec![8u8, 9, 10];
    let mut ref_v = VecRef(&v);
    create(&mut ref_v);
}

fn create<'b, 'a>(r: &'b mut VecRef<'a>) {
    VecRefRef(r);
}
生存期
'b
类似于
'b
,因此违反了
vecreref
中的约束

我将可变引用的生存期与
VecRef
中借用的数据联系起来,将可变引用引用到
VecRef
create()
内部的可变引用
r
的生存期为
VecRef
警告:我所说的是我所没有的专业水平。鉴于这篇文章的篇幅,我可能错了很多次

TL;DR:顶级值的生存期是协变的。引用值的生存期是不变的

介绍问题
通过替换
VecRefI,您可以显著简化示例。在create函数主体内,拾取的生命周期将在2-3的范围内,因为从提供的混凝土生命周期集合中,它将是唯一与约束匹配的生命周期。因此,它将是所创建向量的生命周期'a请注意,您必须使用语法
'b:'a
来表示生命周期
'a
将比
'b更长。
-它不应该是“…表示生命周期
'b
将比
'a
更长”?读取可防止
'b
增长,因为如果要从外部指针中提取内部指针,则可以在
'a
过期后读取你能详细解释一下吗?@soupyboonics我想我错了。让我再打给你。@soupyboonics对不起,我好像忘了你的问题。我记得我调查过,认为我错了,但我记不起细节了。我会注意到
&'static&'b
可以转换为
&'static&'static
,这表明您是对的,但我认为这不正确。相反,可能存在一种隐含的假设,即
'b:'a
;将
&'a&'b
转换为
&'a&'static
失败。
fn create<'a>(r: &'a mut VecRef<'a>) {
    VecRefRef(r);
}
struct VecRef<'a>(&'a Vec<u8>);

struct VecRefRef<'a>(&'a VecRef<'a>); // now an immutable reference

fn main() {
    let v = vec![8u8, 9, 10];
    let mut ref_v = VecRef(&v);
    create(&mut ref_v);
}

fn create<'b, 'a>(r: &'b mut VecRef<'a>) {
    VecRefRef(r);
}
fn identity<'a, T>(val: &'a T) -> &'a T { val }
fn main() {
    let v = vec![8u8, 9, 10];   // 1 |-lifetime of `v`
    let mut ref_v = VecRef(&v); // 2 |  |-lifetime of `ref_v` 
    create(&mut ref_v);         // 3 |  |
}
fn create<'a>(r: &'a mut VecRef<'a>)
struct VecRefRef<'a, 'b: 'a>(&'a mut VecRef<'b>);
fn create<'a, 'b>(r: &'a mut VecRef<'b>)
fn use_same_ref_ref<'c>(reference: &'c mut &'c mut ()) {}
fn use_same_ref_ref<'c>(reference: &'c mut &'c mut ()) {}

fn use_ref_ref<'a, 'b>(reference: &'a mut &'b mut ()) {
    use_same_ref_ref(reference);
}
fn use_same_ref_ref<'c>(reference: &'c mut &'c mut ()) {}

fn use_ref_ref<'a>(reference: &'a mut &'a mut ()) {
    use_same_ref_ref(reference);
}
let mut val = ();
let mut reference = &mut val;
let ref_ref = &mut reference;

use_ref_ref(ref_ref);
fn use_same_ref_ref<'c>(reference: &'c mut &'c mut ()) {}

fn use_ref_ref<'a: 'b, 'b>(reference: &'a mut &'b mut ()) {
    use_same_ref_ref(reference);
}
fn use_same_ref_ref<'c>(reference: &'c mut &'c mut ()) {}

fn use_ref_ref<'a, 'b: 'a>(reference: &'a mut &'b mut ()) {
    use_same_ref_ref(reference);
}
fn use_same_ref_ref<'c>(reference: &'c &'c mut ()) {}

fn use_ref_ref<'a, 'b>(reference: &'a &'b mut ()) {
    use_same_ref_ref(reference);
}
fn use_same_ref_ref<'c>(reference: &'c mut &'c ()) {}

fn use_ref_ref<'a, 'b>(reference: &'a mut &'b ()) {
    use_same_ref_ref(reference);
}
let new_ref = reference;
let new_ref_ref = ref_ref;
let ref_ref: &'x mut &'a mut i32 = ...;

{
    // Has lifetime 'b, which is smaller than 'a
    let new_val: i32 = 123;

    // Shrink 'a to 'b
    let new_ref_ref: &'x mut &'b mut i32 = ref_ref;

    *new_ref_ref = &mut new_val;
}

// new_ref_ref is out of scope, so ref_ref is usable again
let ref_ref: &'a mut i32 = *ref_ref;
// Oops, we have an &'a mut i32 pointer to a dropped value!
fn use_same_ref_ref<'c>(reference: &'c mut &'c mut ()) {}

fn use_ref_ref<'a, 'b>(reference: &'a mut &'b mut ()) {
    use_same_ref_ref(reference);
}
&'a mut &'b mut ()  →  &'c mut &'c mut ()
&'a mut &'b mut ()  →  &'b mut &'b mut ()
'a: 'b
fn use_same_ref_ref<'c>(reference: &'c mut &'c mut ()) {}

fn use_ref_ref<'a>(reference: &'a mut &'a mut ()) {
    use_same_ref_ref(reference);
}
fn use_same_ref_ref<'c>(reference: &'c mut &'c mut ()) {}

fn use_ref_ref<'a: 'b, 'b>(reference: &'a mut &'b mut ()) {
    use_same_ref_ref(reference);
}
fn use_same_ref_ref<'c>(reference: &'c mut &'c mut ()) {}

fn use_ref_ref<'a, 'b: 'a>(reference: &'a mut &'b mut ()) {
    use_same_ref_ref(reference);
}
fn use_same_ref_ref<'c>(reference: &'c &'c mut ()) {}

fn use_ref_ref<'a, 'b>(reference: &'a &'b mut ()) {
    use_same_ref_ref(reference);
}
let ref_ref: &'x mut &'a mut i32 = ...;

{
    // Has lifetime 'b, which is smaller than 'a
    let new_val: i32 = 123;

    // Shrink 'a to 'b
    let new_ref_ref: &'x mut &'b mut i32 = ref_ref;

    *new_ref_ref = &mut new_val;
}

// new_ref_ref is out of scope, so ref_ref is usable again
let ref_ref: &'a mut i32 = *ref_ref;
// Oops, we have an &'a mut i32 pointer to a dropped value!
fn use_same_ref_ref<'c>(reference: &'c mut &'c ()) {}

fn use_ref_ref<'a, 'b>(reference: &'a mut &'b ()) {
    use_same_ref_ref(reference);
}
let ref_ref: &'x mut &'a i32 = ...;

{
    // Has lifetime 'b, which is smaller than 'a
    let new_val: i32 = 123;

    // Shrink 'a to 'b
    let new_ref_ref: &'x mut &'b i32 = ref_ref;

    *new_ref_ref = &new_val;
}

// new_ref_ref is out of scope, so ref_ref is usable again
let ref_ref: &'a i32 = *ref_ref;
// Oops, we have an &'a i32 pointer to a dropped value!
fn use_same_ref_ref<'c>(reference: &'c mut &'c mut ()) {}

fn use_ref_ref<'a: 'b, 'b>(reference: &'a mut &'b mut ()) {
    use_same_ref_ref(reference);
}
let mut val = ();
let mut reference = &mut val;
let ref_ref = &mut reference;

use_ref_ref(ref_ref);
fn use_ref_ref<'a: 'b, 'b>(reference: &'a mut &'b mut ()) {
    use_same_ref_ref(reference);
}
let reference = &mut val;