我有this piece of code个:

#[derive(Debug)]
struct Foo<'a> {
    x: &'a i32,
}

impl<'a> Foo<'a> {
    fn set(&mut self, r: &'a i32) {
        self.x = r;
    }
}

fn main() {
    let v = 5;
    let w = 7;
    let mut f = Foo { x: &v };

    println!("f is {:?}", f);

    f.set(&w);

    println!("now f is {:?}", f);
}

我的理解是,在值v的第一次borrow 中,struct声明中的泛型生存期参数'a被填充为值v的生存期.这意味着生成的Foo对象的生命周期 不得超过'a的生命周期 ,或者v的值必须至少与Foo对象的生命周期 相同.

在对方法set的调用中,使用impl块上的生存期参数,并在方法签名中为'a填充值w的生存期.编译器为&mut self分配了不同的生存期,即f(Foo对象)的生存期.如果在main函数中切换wf的绑定顺序,这将导致错误.

我想知道如果我在set方法中使用与r相同的生命周期参数'a注释&mut self引用,会发生什么:

impl<'a> Foo<'a> {
    fn set(&'a mut self, r: &'a i32) {
        self.x = r;
    }
}

这将导致以下错误:

error[E0502]: cannot borrow `f` as immutable because it is also borrowed as mutable
  --> src/main.rs:21:31
   |
19 |     f.set(&w);
   |     - mutable borrow occurs here
20 | 
21 |     println!("now f is {:?}", f);
   |                               ^ immutable borrow occurs here
22 | }
   | - mutable borrow ends here

与上面的例子相反,在第二次打印时,f仍然被认为是可变borrow 的!被调用,因此它不能作为不变的同时被borrow .

这是怎么回事?

在第一个例子中,编译器没有省略生命周期注释,为我填写了一个&mut self.这是根据终身省略的规则发生的.然而,在第二个例子中,通过显式地将其设置为'a,我将fw的生命周期 联系起来.

不知何故,f被认为是自己借来的吗?

And if so, what is the scope of the borrow? Is it min(lifetime of f, lifetime of w) -> lifetime of f?

我想我还没有完全理解函数调用中的&mut self引用.我的意思是,函数返回,但f仍然被认为是borrow 的.

我正在努力完全理解人生.我主要是寻找关于我对概念理解的纠正性反馈.我非常感谢您提供的每一点建议和进一步的澄清.

推荐答案

在对方法set的调用中,使用impl块上的生存期参数,并在方法签名中为'a填充值w的生存期.

不会.生命周期参数'a的值在Foo struct 的创建时是固定的,并且永远不会更改,因为它是其类型的一部分.

在您的例子中,编译器实际上为'a Select 了一个与vw的生存期兼容的值.如果这是不可能的,它将失败,例如在本例中:

fn main() {
    let v = 5;
    let mut f = Foo { x: &v };

    println!("f is {:?}", f);
    let w = 7;
    f.set(&w);

    println!("now f is {:?}", f);
}

哪些输出:

error[E0597]: `w` does not live long enough
  --> src/main.rs:21:1
   |
18 |     f.set(&w);
   |            - borrow occurs here
...
21 | }
   | ^ `w` dropped here while still borrowed
   |
   = note: values in a scope are dropped in the opposite order they are created

正是因为v施加的'a生命周期 与w的更短生命周期 不兼容.

在第二个示例中,通过强制self的生存期也为'a,您也将可变borrow 绑定到生存期'a,因此,当生存期'a的所有项都超出范围时,即vw,borrow 结束.

Rust相关问答推荐

无法在线程之间安全地发送future (&Q;)&错误

在没有引用计数或互斥锁的情况下,可以从Rust回调函数内的封闭作用域访问变量吗?

使用pyo3::Types::PyIterator的无限内存使用量

如何仅使用http机箱发送http请求?

使用 struct 外部的属性来改变 struct 的原始方式

如何使用 list 在Rust for Windows中编译?

如何使用RefCell::JOYMOMTborrow 对 struct 不同字段的可变引用

使用 serde::from_value 反序列化为泛型类型

有什么方法可以通过使用生命周期来减轻嵌套生成器中的当生成器产生时borrow 可能仍在使用错误?

使用 lalrpop 在 rust 中解析由 " 引用的字符串

仅当函数写为闭包时才会出现生命周期错误

Rust 异步和 AsRef 未被发送

使用方法、关联函数和自由函数在 Rust 中初始化函数指针之间的区别

如何在 Rust 中返回通用 struct

用逗号分隔字符串,但在标记中使用逗号

是否有适当的方法在参考 1D 中转换 2D 数组

通用函数中的生命周期扣除和borrow (通用测试需要)

当用作函数参数时,不强制执行与绑定的关联类型

基于名称是否存在的条件编译

为什么 `ref` 会导致此示例*取消引用*一个字段?