我使用rust-postgres使用以下Rust代码,目的是在我的struct超出范围后提交事务
struct SqlTransaction<'a> {
connection: &'a Connection,
transaction: Transaction<'a>,
}
impl<'a> Drop for SqlTransaction<'a> {
fn drop(&mut self) {
let result = self.transaction.commit();
match result {
Ok(_) => print!("herp"),
Error => print!("lol"),
}
}
}
编译器通过以下消息抱怨commit()
行
cannot move out of type `SqlTransaction<'a>`, which defines the `Drop` trait [E0509]at line 12 col 22
发生了什么,我该如何解决?
答案 0 :(得分:5)
Transaction::commit
方法consumes the transaction:
pub fn commit(self) -> Result<()> {
self.set_commit();
self.finish()
}
如果 能够调用commit
,那么self
的值将处于某种不一致的状态,因为self.transaction
的值是什么?它被搬走了!
如果类型没有实现Drop
,这不会有问题,因为编译器会删除结构的所有其他部分。但是,因为它实现了Drop
,所以你永远不能分开结构,因为Drop
无法运行!当您进入Drop
实现本身时,这甚至适用。
如果您确实需要执行此操作,则必须使transaction
成为您可以轻松替换的某种类型。 Option
是一个不错的选择,因为您可以使用take
将其替换为None
。
在Transaction
的特定情况下,您不必做任何特别的事情。虽然Transaction
通常会回落,但您可以调用Transaction::set_commit
以便它在提交时提交。