web-dev-qa-db-ja.com

クロージャーはFn、FnMut、FnOnceをいつ実装しますか?

クロージャーがFnFnMutおよびFnOnce特性を実装するための特定の条件とは何ですか?

あれは:

  • いつクロージャーnotFnOnce特性を実装しますか?
  • いつクロージャーnotFnMut特性を実装しますか?
  • いつクロージャーnotFn特性を実装しますか?

たとえば、本体のクロージャの状態を変更すると、コンパイラはFnを実装しません。

86
Denilson Amorim

特性はそれぞれ、クロージャー/関数に関するますます制限的なプロパティを表し、call_...メソッドのシグネチャ、特にselfのタイプによって示されます。

  • FnOnceself)は1回呼び出すことができる関数です。
  • FnMut&mut self)は、環境に&mutアクセスできる場合に呼び出すことができる関数です
  • Fn&self)は、環境へのアクセスが&のみの場合に呼び出すことができる関数です。

クロージャ|...| ...は、できるだけ多くのものを自動的に実装します。

  • すべてのクロージャーはFnOnceを実装します:一度呼び出せないクロージャーは名前に値しません。クロージャがFnOnceのみを実装する場合、一度しか呼び出せないことに注意してください。
  • キャプチャから移動しないクロージャーは、FnMutを実装し、複数回呼び出せるようにします(関数オブジェクトへのエイリアスのないアクセスがある場合)。
  • キャプチャへの一意/可変アクセスを必要としないクロージャは、Fnを実装し、本質的にどこでも呼び出せるようにします。

これらの制限は、selfの型とクロージャーの構造体への「脱糖」から直接に従います( Rustでのクロージャーの検索で説明 )。

Rust 2017年時点のクロージャーの詳細については、 Rust book)のクロージャーの章 を参照してください。

100
huon