我有一个结构和各自的实现:
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;
vec.push(acct);
Self {
id: self.id,
linked_accounts: vec,
}
}
}
error[E0507]: cannot move out of `self.linked_accounts` which is behind a mutable reference
--> src/lib.rs:10:37
|
10 | let mut vec: Vec<Account> = self.linked_accounts;
| ^^^^^^^^^^^^^^^^^^^^ move occurs because `self.linked_accounts` has type `Vec<Account>`, which does not implement the `Copy` trait
|
help: consider borrowing here
|
10 | let mut vec: Vec<Account> = &self.linked_accounts;
| +
error[E0507]: cannot move out of `self.id` which is behind a mutable reference
--> src/lib.rs:14:17
|
14 | id: self.id, //*Error here*
| ^^^^^^^ move occurs because `self.id` has type `String`, which does not implement the `Copy` trait
我在从数据库加载部门、添加帐户并将其存储回数据库时使用它:
match db.get::<Departments>(id).await? {
None => bail!("No records found"),
Some(departments) => {
let mut departments = departments;
departments.add_account(Account::Credit);
let id = Id::new(Departments::KIND, &id);
gh.update::<_, Departments>(id, departments.clone()).await?;
}
}
我该如何解决这个问题?
有几种方法可以解释您的问题。在所有情况下,答案都以 “您的函数签名是错误的” 开头,但它到底应该是什么,取决于您的用例。
但最肯定的是,它应该是以下之一:
pub fn add_account(&mut self, acct: Account)
pub fn add_account(&mut self, acct: Account) -> &mut Self
pub fn add_account(mut self, acct: Account) -> 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);
这通常是通过返回
&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
}
}
请注意,这个 still
不需要您实例化一个新的
Self
对象,就像您在代码中所做的那样。如果您想了解原始错误:
&mut self
的说法意味着你只借了
self
let mut vec: Vec<Account> = self.linked_accounts;
将linked_accounts
成员移出self
。只有当我们拥有self
而不是借用它时,这才有可能,因为这样,我们就可以按照自己的意愿拆除它。但由于我们需要归还它,所以我们不能只是将成员移出。我没有更详细地讨论实际错误,因为它只是错误函数签名的产物,并没有真正对解决方案做出有意义的贡献。
无论哪种方式,我认为您对所有权如何运作存在一些误解,所以我建议阅读 Rust 书中的所有权章节。
我认为您有误解的原因是,如果您的函数签名包含
Self
,则实际上不可能返回&mut self
。 Self
是拥有的,如果不复制借用的对象,则无法创建拥有的对象。
是的,您正在尝试创建它的副本以尝试实现它,但您发布的使用示例向我表明您实际上并不想创建副本。