【问题标题】:How to modify the &mut self contents and return self如何修改 &mut self 内容并返回 self
【发布时间】:2023-01-23 01:17:32
【问题描述】:

我也有一个结构和相应的 impl (add_account)。

结构体

pub struct Departments {
    pub id: String,
    pub linked_accounts: Vec<Account>,
}

实施

impl Departments {
    pub fn add_account(&mut self, acct: Account) -> Self {

        let mut vec: Vec<Account> = self.linked_accounts; //*Error here*
        vec.push(acct);

        Self {
            id: self.id, //*Error here*
            linked_accounts: vec,
        }
    }
}

通话区

从数据库中获取价值并添加帐户并更新回数据库

match db.get::<Departments>(id).await? {
        None => bail!("No records found"),
        Some(departments) => {
            let mut departments = departments;

            //calling area
            departments.add_account(Account::Credit);

            let id = Id::new(Departments::KIND, &id);
            gh.update::<_, Departments>(
                id,
                departments.clone(),
            )
                .await?;
            
        }
    }

在内部分配自我值时出现 'Cannot move self' 错误。

【问题讨论】:

  • 这可能是一个 XY 问题。无论如何,我们需要更多细节。
  • 我需要在结构“部门”中附加一个向量“帐户”值,这非常简单。我正在调用“dept.add_account(Account::EnumVal)”,其中帐户为枚举
  • 我的意思是关于为什么您特别需要使用 &amp;mut self 调用并返回拥有的 Self 的更多详细信息。
  • 主要目标不是传递调用区域的所有权,我可能需要在调用区域中分配一个新变量,所以我传递为“&mut self”
  • 请提供更多上下文。调用代码的示例会很好。

标签: rust struct self borrow-checker vec


【解决方案1】:

有几种方法可以解释您的问题。在所有情况下,答案都以“你的函数签名是错误的”,但具体应该是什么取决于您的用例。

但最肯定的是,它应该是以下之一:

  • pub fn add_account(&amp;mut self, acct: Account)
  • pub fn add_account(&amp;mut self, acct: Account) -&gt; &amp;mut Self
  • pub fn add_account(mut self, acct: Account) -&gt; Self

我认为你最大的误解是你认为你需要返回Self。您使用 add_account 的方式,只需在 departments.add_account(Account::Credit) 上调用它即可不是要求你返回Self。可以直接修改self对象:

pub struct Departments {
    pub id: String,
    pub linked_accounts: Vec<Account>,
}

impl Departments {
    pub fn add_account(&mut self, acct: Account) {
        self.linked_accounts.push(acct);
    }
}

现在,有一个用例,您希望返回某种形式的 Self,如果您希望能够链接这些调用:

departments
    .add_account(Account::Credit)
    .add_account(Account::Debit)
    .add_account(Account::Savings);

这通常通过返回&amp;mut Self来完成:

pub struct Departments {
    pub id: String,
    pub linked_accounts: Vec<Account>,
}

impl Departments {
    pub fn add_account(&mut self, acct: Account) -> &mut Self {
        self.linked_accounts.push(acct);
        self
    }
}

请注意,这仍然不需要您实例化一个新的 Self 对象,就像您在代码中所做的那样。


实际错误

如果您想了解原始错误:

  • &amp;mut self 的意思是你只借用self,你必须在某个时候归还它。 (在函数结束时自动发生)
  • let mut vec: Vec&lt;Account&gt; = self.linked_accounts;移动linked_accounts 会员出去来自self。这只有在我们获得 self 的所有权而不是借用它时才有可能,因为那样的话,我们就可以随心所欲地拆除它。但由于我们需要回馈它,我们不能只是将成员移出它。

我没有更详细地讨论实际错误,因为它只是错误函数签名的产物,并没有真正对解决方案做出有意义的贡献。

无论哪种方式,我认为您对所有权的工作方式存在一些误解,因此我建议您阅读 Rust 书中的ownership chapter

我认为您有误解的原因是,如果您的函数签名包含&amp;mut self,则实际上不可能返回SelfSelf 是拥有的,您不能在不复制的情况下从借来的对象创建拥有的对象。

是的,您在尝试实现它时试图创建它的副本,但是您发布的用法示例向我表明您实际上并不想创建副本。

【讨论】:

  • 非常感谢,它有效..我一定会阅读你的建议..
【解决方案2】:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-27
  • 1970-01-01
相关资源
最近更新 更多