不能移出定义`Drop`特征的类型[E0509]

时间:2015-12-14 23:39:51

标签: rust

我使用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

发生了什么,我该如何解决?

1 个答案:

答案 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以便它在提交时提交。