捕捉時の型推論
Rustはたいていの場合、型アノテーションなしでも変数を捕捉する方法を臨機応変に選択してくれますが、関数を書く場合にはこの曖昧さは許されません。
引数のパラメータとしてクロージャを取る場合、そのクロージャの完全な型はいくつかのtraits
の中の1つを使って明示されなければなりません。
どれが使われるかは、捕捉された値でクロージャが何をするかによって決まります。
制限の少ない順に並べると、下記の通りです。
Fn
: 参照(&T
)によって捕捉するクロージャFnMut
: ミュータブルな参照(&mut T
)によって捕捉するクロージャFnOnce
: 値(T
)によって捕捉するクロージャ
変数ごとに、コンパイラは可能な限り制約の少ない方法でその変数を捕捉します。
例えば、FnOnce
というアノテーションの付けられたパラメータを考えてみましょう。
これはそのクロージャが&T
、&mut T
もしくはT
の どれか で捕捉することを指定するものですが、コンパイラは捕捉した変数がそのクロージャの中でどのように使用されるかに基づき、最終的に捕捉する方法を選択することになります。
これは、もし移動が可能であれば、いずれの種類の借用であっても同様に可能だからです。
その逆は正しくないことに注意してください。パラメータがFn
としてアノテーションされている場合、変数を&mut T
やT
で捕捉することは許可されません。
しかし&T
は許可されます。
以下の例では、Fn
、FnMut
、およびFnOnce
を入れ替えて、何が起こるのかを見てみましょう。