2017-11-10 83 views
-3

我在TimeTravel中嘗試更改date的值。評論表明我想要什麼樣的價值,但這不是我得到的。如何從閉包修改閉包之外的值?

use std::cell::Cell; 

#[derive(Debug, Clone)] 
pub struct TimeTravel { 
    pub date: Cell<i32>, 
} 

impl TimeTravel { 
    pub fn new() -> Self { 
     TimeTravel { date: Cell::new(1) } 
    } 

    pub fn forward(&self) -> &Self { 
     let d = self.date.get(); 
     self.date.set(d + 1); 
     self 
    } 
} 

fn main() { 
    let travel: TimeTravel = TimeTravel::new(); 
    println!("{:?}", travel); // 1 
    travel.forward(); 
    println!("{:?}", travel); // 2 

    { 
     let t1 = travel.clone(); 
     let first = || { 
      t1.forward(); 
      println!("{:?}", t1); // 3 
      t1.forward(); 
      println!("{:?}", t1); // 4 
     }; 
     first(); 
    } 

    { 
     let t2 = travel.clone(); 
     let second = || { 
      t2.forward(); 
      println!("{:?}", t2); //5 
     }; 
     second(); 
    } 
} 

不過,我得到這個

TimeTravel { date: Cell { value: 1 } } 
TimeTravel { date: Cell { value: 2 } } 
TimeTravel { date: Cell { value: 3 } } 
TimeTravel { date: Cell { value: 4 } } 
TimeTravel { date: Cell { value: 3 } } 

如果我理解正確的正在發生的事情,我在t1t2,而不是travel更改值。如何更改閉包內travel的值?

Example in Rust Playground

+2

如果你想變異'travel'爲什麼要克隆嗎? https://play.rust-lang.org/?gist=a7a21ff881217d703b53209307254b88&version=每夜工作得很好。也許你真正的代碼更復雜,並且用閉包做更復雜的事情? – loganfsmyth

+0

因爲我是一個完整的生鏽初學者,克隆是我知道避免「移動」問題的唯一途徑,或者不是在「已借」或恐慌中跑步。我想在旅行中增加日期,所以最後一個會打印5(通過引用?),這就是我在這裏問的原因。 –

+0

是的,真正的代碼更復雜,這是一個簡化版本的問題。 –

回答

1

我強烈建議回去和重新閱讀鏽病編程語言,第二版,specifically the chapter on ownership。之後,檢查出的文檔Clone,重點煤礦:

的能力明確地複製對象的共同特徵。

當您撥打.clone()時,您將創建對象的新副本,與原始對象完全不同。對克隆的任何更改都不適用於原始內容。

正如評論所說,你需要用travel刪除所有引用t1t2和替換它們:

{ 
    let first = || { 
     travel.forward(); 
     println!("{:?}", travel); // 3 
     travel.forward(); 
     println!("{:?}", travel); // 4 
    }; 
    first(); 
} 

{ 
    let second = || { 
     travel.forward(); 
     println!("{:?}", travel); //5 
    }; 
    second(); 
} 
+0

我簡化的例子太多了,雖然這個例子修正了它並沒有真正的代碼。真正的例子有'移動'關閉,它需要改變'DateTime'。不得不用'borrow_mut()'來使用'Rc >'來獲得這個工作。不管怎麼說,還是要謝謝你 –