首页 文章

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

提问于
浏览
2

我有使用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 回答

  • 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以便它在下降时提交 .

相关问题