为什么指定了生命周期的方法不能被调用两次?

huangapple go评论65阅读模式
英文:

Why method with lifetime specified cannot be called twice?

问题

struct A<'a> {
    v: &'a str,
}

impl<'a> A<'a> {
    pub fn test(&'a mut self) {
        self.trivial();

        // Compiling error info:
        // cannot borrow `*self` as mutable more than once at a time
        // first mutable borrow occurs here (last called self.trivial())
        self.trivial(); // Compiling error line.
    }

    // Trivial empty function.
    fn trivial(&'a mut self) {}
}

编译错误发生在第二次调用 self.trivial(),编译器提示这是第一次以可变方式借用 *self。如果将 trivial 函数的生命周期 'a 移除,一切就会正常运行。

我的问题是为什么生命周期 'a 会影响借用?我认为 trivial 函数的参数类型是 &mut,只接受参数而不进行借用,为什么第一次调用会借用?


<details>
<summary>英文:</summary>

struct A<'a> {
v: &'a str,
}

impl<'a> A<'a> {
pub fn test(&'a mut self) {
self.trivial();

    // Compiling error info:
    //       cannot borrow `*self` as mutable more than once at a time
    // first mutable borrow occurs here (last called self.trivial())
    self.trivial(); // Compiling error line.
}

// Trivial empty function.
fn trivial(&amp;&#39;a mut self) {}

}


The compiling errors happen at the second called `self.trivial()` and compiler hints that it&#39;s the first calling `self.trivial` mutably borrow `*self`. And if the trivial function is defined by removing the lifetime &#39;a then everything is fine.

// ok then if no 'a specified.
fn trivial(&mut self) {}

My question is why does the lifetime `&#39;a` influence the borrowing? I think function `trivial` has the parameter with type `&amp;mut` which just accepts the argument and not borrow at all, how does the first calling borrow?

</details>


# 答案1
**得分**: 3

生命周期的名称很重要。当您将其指定为`'a`时,您是在说给定给`trivial`的`&mut self`引用必须保持在结构体本身的生命周期内可访问。这意味着在第一次调用`trivial`之后它不会被“释放”。如果您将其更改为`trivial`具有自己的生命周期:

```rust
fn trivial<'b>(&'b mut self) {}

现在它将正常工作,因为借用仅在函数调用的时间内持续。如果您完全删除生命周期注释,那么隐式地发生的情况也是一样的。

请注意,将&mut self(或任何引用)传递到函数中实际上是一种借用——当该参数是引用时,“接受一个参数而不借用”并不真正有意义。

英文:

The name of the lifetime matters. When you give it &#39;a as an explicit lifetime, you're saying the &amp;mut self ref given to trivial must remain accessible for the lifetime of the struct itself. Which means it doesn't get "released" after the first call to trivial. If you change that to trivial having its own lifetime:

fn trivial&lt;&#39;b&gt;(&amp;&#39;b mut self) {}

Now it'll work fine because the borrow only lasts as long as the function call. This is the same thing that's happening implicitly if you remove the lifetime annotation entirely.

Note that passing a &amp;mut self (or any reference) into a function is a borrow -- "accepts an argument and not borrow at all" doesn't really make sense when that argument is a ref.

huangapple
  • 本文由 发表于 2023年6月11日 21:30:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76450702.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定