関数型を公称型(つまり、構造体または列挙型)にラップすることができます。錆のtype
はC.でHaskellではtype
とtypedef
ので、1つのテースト、単なる別名である一方でtype T U
は、U
と直接交換可能ではありません新しい、特殊タイプT
を定義しています。これは、実際に行くのコードがやっていることです書き込み:
struct StateFn(fn() -> Option<StateFn>);
または
struct StateFn {
f: fn() -> Option<StateFn>
}
(私はOption
ために行くのを追加しなければなりませんでした錆が、それはオプトインを作り、デフォルトでNULL値の許容を取り除きながら、nilにすることができます。)
前記、ルストfn
だけである一方で、私は、(いくつかの内部状態を保存することができます)func
が行くで閉鎖されると思われます(全くステートはありません)ので、Rustでもクロージャーを使いたいかもしれません。これは、fn() -> Option<StateFn>
をBox< Fn() -> Option<StateFn>>
に置き換えて、Box::new(move || { /* code here */ })
で作成することで可能です。
Fn
の代わりにFnMut
を使用することもできます。これにより、柔軟性が向上します。FnOnce
は一度しか呼び出せないクロージャを表します。これらのそれぞれは、呼び出し元に対する連続的な制限を設けていますが、クロージャそのものに次々と柔軟性を与えています。 (ただし、「オブジェクトの安全性」の懸念がBox<FnOnce>
は、現時点では動作しないことを意味し、"Purging proc"は詳細と回避策があります。)
struct StateFn {
f: Box<FnMut() -> Option<StateFn>>
}
これらのいずれかの状況の解析ループは次のようになります。
let mut state_fn = Some(initial_fn);
while let Some(mut f) = state_fn {
state_fn = (*f.f)()
}
Fnは呼び出し元に最も制限をかけます(環境を変更しないでください).FnOnceは環境を消費/移動することさえできます。 FnOutはFnMutに実装され、FnMutはFnに実装されます。私はここでFnOnceが最適だと思う。 –
いいえ、*呼び出し側*は 'Fn'に対して最も制限がありません。 'FnMuth'や' FnOnce'のどちらも呼び出すことができませんが、 'FnOnce'はby-valueで呼び出されなければならず、一度だけ呼び出すことができます(これははるかに制限的です) 。一方、 'Fn'は* callee *(クロージャ自体)に最も制限を設け、' FnOnce'はクロージャのために最も制限の少ないものです(つまり、 'FnOnce'クロージャのボディが最も柔軟性があります)。答えが説明しているように、 'FnOnce'が最高ですが、特性オブジェクトの周りに微妙なところがあります。つまり、それは直接作用しません。 – huon
はい、そうです。私は引数としてFnOnce/FnMut/Fnをとる関数を考えました。 –