2015-12-14 38 views
2

我使用rust-postgres我的結構後提交事務的意圖下面鏽代碼超出範圍不能搬走它定義了`Drop`特質類型[E0509]

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"), 

     } 
    } 
} 

編譯器抱怨以下消息

cannot move out of type `SqlTransaction<'a>`, which defines the `Drop` trait [E0509]at line 12 col 22 

發生什麼事,我怎麼能解決這個問題的commit()線?

回答

3

Transaction::commit方法consumes the transaction

pub fn commit(self) -> Result<()> { 
    self.set_commit(); 
    self.finish() 
} 

如果能夠調用commit,那麼self值將是一些不一致的狀態,因爲你會的self.transaction的價值是什麼?它已被移出!

如果類型沒有實現Drop,這不會是一個問題,因爲編譯器會放棄結構的所有其他部分。但是,由於它實現了Drop,所以你永遠無法拆開結構,因爲Drop無法運行!這甚至適用於當你在執行本身時。

如果您確實需要這樣做,您必須將transaction設置爲您可以輕鬆替換的某種類型。 Option是一個不錯的選擇,因爲您可以使用take將其替換爲None


Transaction的特定情況下,您不必做任何特殊的事情。雖然Transaction通常在放棄時回滾,但您可以撥打Transaction::set_commit以使其落下。