Reference 可变引用生存期与不可变引用生存期

Reference 可变引用生存期与不可变引用生存期,reference,rust,immutability,mutable,lifetime,Reference,Rust,Immutability,Mutable,Lifetime,我有以下代码: struct Bar<T> { k: [T; 10], } impl<T> Bar<T> { fn thing(&self, i: usize) -> &T { &self.k[i] } fn thing_mut(&mut self, i: usize) -> &mut T { &mut self.k[i] }

我有以下代码:

struct Bar<T> {
    k: [T; 10],
}

impl<T> Bar<T> {
    fn thing(&self, i: usize) -> &T {
        &self.k[i]
    }

    fn thing_mut(&mut self, i: usize) -> &mut T {
        &mut self.k[i]
    }
}

struct Foo<'a, T: 'a> {
    bar: &'a Bar<T>,
    count: usize,
}

impl<'a, T> Foo<'a, T> {
    fn get(&mut self) -> Option<&'a T> {
        if self.count < 10 {
            let thing = self.bar.thing(self.count);
            self.count += 1;
            Some(thing)
        } else {
            None
        }
    }
}

struct FooMut<'a, T: 'a> {
    bar: &'a mut Bar<T>,
    count: usize,
}

impl<'a, T> FooMut<'a, T> {
    fn get(&mut self) -> Option<&'a mut T> {
        if self.count < 10 {
            let thing = self.bar.thing_mut(self.count);
            self.count += 1;
            Some(thing)
        } else {
            None
        }
    }
}

为什么不可变的编译得很好,而可变的编译得不好?在
FooMut
案例中是否缺少一些终生注释?我已经看到了很多关于生命周期和引用的答案,但在本例中,我特别询问了可变与不可变的情况。

不可变和可变引用的生命周期方面已经在不同的地方进行了讨论: 请参阅问题的注释和答案中的参考资料

我在这里写了一些关于这个具体案例的笔记,希望能对锈蚀寿命这一困难的概念有所启发 (至少对我来说这很难)

考虑一下这个片段,它是一个简化版本,暴露了问题的相同问题:

struct Foo<'a> {
    x: &'a mut i32,
}

impl<'b> Foo<'b> {
    fn x(&mut self) -> &'b mut i32 { self.x }
}

fn main() {
    let y = &mut 5;              // <- 'a(1)
    let mut f = Foo { x: y };    //    'a(1) <- 'b(2)
    println!("x is: {}", f.x()); //    'a(1)    'b(2) <- 'anonymous(3)
}
我们看到,
'anonymous
的生命周期比
'b
的生命周期要窄(请参见代码注释中的“近似”生命周期可视化):借用的内容
self.x
的生命周期不足以满足生锈安全规则

现在很明显,解决方案应该是通过显式注释减少生命周期,或者在规则的支持下更好地减少生命周期:


有关更多详细信息,请参阅。

我相信您的问题已由回答。如果不是这样,或者很可能会回答。请解释您的问题与这些现有问题的不同之处。如果不是,我们可以将此标记为已回答。谢谢您的回答。“如果内部引用是不可变的,则编译器可以确保不会因缩小生存期范围而出现内存问题。”。你所说的“缩小寿命范围”是什么意思?self.x不应该有f实例的生存期吗?哪个变量的生存期范围缩小了?
self.x
(意指引用self.x的生存期)和对
Foo
的引用,因为
Foo::x(&mut self)
的&self参数可能有不同的生存期。关于缩小生命周期范围的含义,请参见我的更新,我希望它可能更清楚。
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
 --> src/main.rs:6:30
  |
6 |     fn x(&self) -> &'b i32 { self.x }
  |                              ^^^^^^
  |
note: ...the reference is valid for the lifetime 'b as defined on the impl at 5:1...
 --> src/main.rs:5:1
  |
5 | impl<'b> Foo<'b> {
  | ^^^^^^^^^^^^^^^^
note: ...but the borrowed content is only valid for the anonymous lifetime #1 defined on     the method body at 6:5
 --> src/main.rs:6:5
  |
6 |     fn x(&self) -> &'b i32 { self.x }
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
struct Foo<'a> {
    x: &'a mut i32,
}

impl<'b> Foo<'b> {
    fn x(&mut self) -> &mut i32 { self.x }
}

fn main() {
    let y = &mut 5;              // <- 'a
    let mut f = Foo { x: y };    //    'a <- 'b
    println!("x is: {}", f.x()); //    'a    'b
}
let mut my_ref: &mut i32 = &mut 1;
let mut f = Foo { x: my_ref }; 
{                                 | <--- narrowed lifetime scope
    let y = &mut 5;               |
    f.x = y;                      |
}                                 | <---
// ERROR: invoking f.x() when self.x is no more valid!
f.x();