変数をクロージャに渡す
説明
デフォルトでは、クロージャは借用する形で環境をキャプチャします。あるいは環境全体をムーブする move
クロージャを使うこともできます。しかしながら、クロージャへ一部の変数のみを対象に、ムーブさせる/データのコピーを与える/参照渡しをする/その他の変換を行う、といったことをしたいことがよくあります。
Use variable rebinding in a separate scope for that.
例
次の例のようにしましょう
#![allow(unused)] fn main() { use std::rc::Rc; let num1 = Rc::new(1); let num2 = Rc::new(2); let num3 = Rc::new(3); let closure = { // num1` はムーブされる let num2 = num2.clone(); // num2` がクローンされる let num3 = num3.as_ref(); // num3` は借用される move || { *num1 + *num2 + *num3; } }; }
上の例は下の例と同等の意味となります
#![allow(unused)] fn main() { use std::rc::Rc; let num1 = Rc::new(1); let num2 = Rc::new(2); let num3 = Rc::new(3); let num2_cloned = num2.clone(); let num3_borrowed = num3.as_ref(); let closure = move || { *num1 + *num2_cloned + *num3_borrowed; }; }
長所
コピーされたデータは、クロージャの定義と一緒にグループ化されるため、その目的がより明確になります。また、もしそれらがクロージャによって消費されない場合でも、即座に削除されることになります。
クロージャは、データがコピーされようがムーブされようが、周辺のコードと同じ変数名を使用します。
短所
クロージャの本体のインデントが増えます。