Rustでクロージャを使ってカウンターを実装するサンプル
クロージャのお勉強用のお題としてよくある、「ある関数から、実行する度に値をインクリメントして返すクロージャを生成して返す」をRustで実装してみました。
RustのクロージャはちょっとApache Groovyなどと比べると癖が有って難しい印象です...(所有権とかが絡んでくるので)
理屈を理解することは当然大切ですが、この辺りはもう慣れっていうのも大事なのかな〜と思って最近は色々小さいコードをRustで書いて色々実験しています。
fn create_counter() -> Box<FnMut() -> i32> { // カウンタのデフォルト let mut x = 0; // 変数xはスタック上に確保されるので、moveを使ってxのコピーの所有権をクロージャに移してあげる。 let clj = move || { x += 1; x }; // Rustは、クロージャを返す場合にはBoxで包んで返して上げる必要がある。 Box::new(clj) } fn main() { let mut counter1 = create_counter(); debug_assert!(counter1() == 1); debug_assert!(counter1() == 2); debug_assert!(counter1() == 3); let mut counter2 = create_counter(); debug_assert!(counter2() == 1); debug_assert!(counter2() == 2); debug_assert!(counter2() == 3); debug_assert!(counter2() == 4); debug_assert!(counter2() == 5); // 当然別のクロージャが持っている環境(変数)に影響なし。 debug_assert!(counter1() == 4); debug_assert!(counter1() == 5); }