2017-01-30 6 views
1

私は、構造体を持っている:ライフタイムを追加すると、すべてのダウンストリーム構造体にライフタイムを追加しないようにする方法はありますか?

struct C { 
    field: Box<Fn()> 
} 

struct D(C) 
struct E(C) 
struct F(D) 

は私が名前の機能に対応するために、代わりに&Fn()Cのフィールドを変更したいです。 Rust構造体の参照フィールドには生涯パラメータが必要なので、問題が発生します。 Cは今でなければなら:

struct C<'a> { 
    field: &'a Fn() 
} 

その後DEFのために、私も生涯のパラメータを指定する必要があります。

struct D<'a>(c<'a>) 
struct E<'a>(C<'a>) 
struct F<'a>(C<'a>) 

Fが多くimplの機能を持っている、DEを想像してみ..多くの場所に生涯パラメータを追加するには、コードを大幅に変更する必要があります。

これを回避する方法はありますか? Cの有効期間パラメータは'staticにはできません。ローカルに定義されたクロージャもあります。

答えて

2

これを回避するには非常に簡単な方法があります。通常の機能にはBox<Fn()>も使用してください。

錆が抽象化された2種類の機能があります。

  • fn()をそうBox<Fn()>を使用すると、あなたは両方を持つことができます関数とクロージャの両方を超える
  • Fn()抄録

「シンプル」の機能を表しています。

ここにはメモリ割り当てがありますが、これは「裸」機能では不要です。あなたは、コード全体をリファクタリングするのではなく、トレードオフを受け入れることができます。

メモリ割り当てを避けることを検討している場合は、Cowを調べるとよいでしょう。

+0

ありがとうございました。また、明確化のためにShipmasterに多くのthx。 – kkspeed

+0

通常の関数はゼロサイズです。ボクシングでは、ゼロサイズの型は割り当てをまったく実行しません(アロケータはポインタに対して単に '1'を返します)。 –

+0

@FrancisGagné:本当ですか?確かにランタイムには、呼び出す関数を知るための関数へのポインタが必要です。 –

3

Matthieu M. has answeredおそらくではなく、あなたの質問あなた問題を解決し、質問「どのように私はすべての生涯を追加避けることができる」、:

は、すべてのダウンストリームに寿命を追加することを回避する方法はあります生涯を追加するときの構造体

いいえ、ありません。生涯の注釈はで、タイプをパラメータ化した別の汎用タイプです。そのタイプを使用するすべてのものは、パラメーター化された具体的な生涯について知っていなければなりません。一生の大きな理由の1つは、安全なシステムを持つために、コンパイラ(そしてあなた!)は、構造体が範囲外になる可能性のあるものへの参照を含んでいることを知る必要があります。 1つは、参照はもはや有効ではありません。

関連する問題