2017-11-10 7 views
-3

dateの値をTimeTravelに変更しようとしています。コメントはどのような価値があるかを示していますが、それは私が得るものではありません。クロージャの外側の値をクロージャからどのように変更できますか?

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=nightlyはうまくいきます。おそらく、あなたの実際のコードはもっと複雑で、クロージャーではもっと複雑なものでしょうか? – loganfsmyth

+0

私は錆の完全な初心者であり、クローニングは "移動"の問題を避けるために、または "既に借りている"またはパニックで走っていないことを知っている唯一の方法です。私は旅行の中で日付を増やして最後のものが5を印刷するようにしたいのですが(参照で?)、私はここで尋ねています。 –

+0

はい、実際のコードはより複雑ですが、これは問題の単純化されたバージョンです。 –

答えて

1

私は非常に錆プログラミング言語、第二版、specifically the chapter on ownershipを戻って、再読み込みをお勧めしたいです。その後、Cloneのドキュメントをチェックアウトし、重点鉱山:

明示的オブジェクトを複製する能力のために共通の特徴。

.clone()に電話すると、元のものとはまったく異なるオブジェクトの新しいコピーが作成されます。クローンへの変更は、オリジナルには適用されません。

としてはコメントで言った、あなたはt1またはt2へのすべての参照を削除し、travelでそれらを交換する必要があります。

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

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

私は例をあまりにも単純化しましたが、これはこの例を修正しましたが、実際のコードを修正しませんでした。実際の例では、 'DateTime'を変更する必要があった' move'クロージャがありました。 'Rc >'を 'borrow_mut()'と一緒に使って、それを動作させる必要がありました。とにかくありがとう –

関連する問題