首页 > 解决方案 > 无法分配,因为它是在返回包含引用的 Result 的结构的方法中借用的

问题描述

似乎我没有在 Rust 中理解借用概念。我有这个简单的例子:

pub struct User {
    name: Option<String>,
}

impl User {
    pub fn new() -> Self {
        Self {
            name: Some("".to_string()),
        }
    }

    pub fn write_name(&mut self) -> Result<(), &str> {
        let name = self.generate_name()?;
        self.name = Some(name);
        Ok(())
    }

    pub fn generate_name(&self) -> Result<String, &str> {
        Ok("John".to_string())
    }
}
error[E0506]: cannot assign to `self.name` because it is borrowed
  --> src/lib.rs:14:9
   |
12 |     pub fn write_name(&mut self) -> Result<(), &str> {
   |                       - let's call the lifetime of this reference `'1`
13 |         let name = self.generate_name()?;
   |                    ----                - returning this value requires that `*self` is borrowed for `'1`
   |                    |
   |                    borrow of `self.name` occurs here
14 |         self.name = Some(name);
   |         ^^^^^^^^^ assignment to borrowed `self.name` occurs here

我需要返回Result,我需要将名称生成与设置名称分开。如何释放借用以便设置self.name变量?

标签: rust

解决方案


函数头

pub fn generate_name(&self) -> Result<String, &str>

可能应该改为

pub fn generate_name(&self) -> Result<String, &'static str>

前者使编译器假设错误类型&str的生命周期与 的生命周期相关联self,因此self在调用站点上被认为是借用的,直到结果超出范围。您的错误类型不太可能借用self- 您更可能希望返回静态字符串作为错误。

您的定义generate_name()在参数列表中有一个隐式生命周期参数——self引用的生命周期——在返回类型中有一个隐式生命周期参数——错误类型的生命周期&str。如果参数列表和返回类型中都只有一个空闲生命周期参数,编译器将应用生命周期省略规则来标识空闲生命周期参数,因为这很可能是您想要的。如果这不是您想要的,就像在这种情况下,您需要明确说明所需的生命周期。


推荐阅读