9

このコードを新しいボックス化されていないクロージャーで書き直すのを誰か手伝ってくれませんか?

struct Builder;
pub fn build(rules: |params: &mut Builder|) -> Builder {
    let mut builder = Builder::new();
    rules(&mut builder);

    builder
}

私はこのように書き込もうとしましたが、生涯エラーが発生しました:

pub fn build<F>(rules: F) -> Builder where F: FnOnce<(&mut Builder,), ()> {
    let mut builder = Builder::new();
    rules(&mut builder);

    builder
}

valico/src/builder.rs:48:59: 48:71 error: missing lifetime specifier [E0106]
valico/src/builder.rs:48     pub fn build<F>(rules: F) -> Builder where F: FnOnce<(&mut Builder,), ()> {
                                                                                   ^~~~~~~~~~~~

指定する必要がある有効期間は? サンドボックスの簡略化された例

4

1 に答える 1

11

これには、より高いランクの特性境界、具体的にはより高いランクの寿命が必要です。完全な unsugared 構文はF: for<'a> FnOnce<(&'a mut Builder,), ()>.

関数でライフタイムを使用しても機能しません。

pub fn build<'b, F>(rules: F) -> Builder where F: FnOnce<(&'b mut Builder,), ()>

これはbuild、呼び出し元が望む任意のライフタイムで動作することを示しています (たとえば、'b==を選択でき'staticます) が、使用する必要がある特定の具体的なライフタイムがあるため、これは無効です:&mut builder関数内のライフタイム。F: for<'a> ...in a boundを使用すると、Fは任意のライフタイム'aで機能するため、コンパイラは、 の 1 つを置き換えることが合法であると判断し&mut builderます。

上でほのめかしたように、これは本当に見苦しい unsugared 構文です。これをより良くする方法は 2 つあります。まず、クロージャー トレイトを使用する標準的な方法は()sugar: ですfor<'a> FnOnce(&'a mut Builder) -> ()。または、残りの Rust と同様に、-> ()を削除できます: for<'a> FnOnce(&'a mut Builder)。(注: これは単なるシュガーですFnOnce<...>が、シュガーされた構文のみが 1.0 でこれらのトレイトと相互作用するために安定化されます。)

次に、paren 構文には少し余分な規則があります。これは、次のように動作するライフタイムを自動的に挿入しますfor<'a>(具体的には、挿入されたライフタイムがトレイトの a に配置されると、ライフタイムの省略が行われます) 。forF: FnOnce(&mut Builder)F: for<'a> FnOnce(&'a mut Builder)

これらの修正を遊び場の例に適用します。

pub fn initialize_with_closure<F>(rules: F) -> uint where F: FnOnce(&mut uint) {
    let mut i = 0;
    rules(&mut i);

    i
}

// equivalently
pub fn initialize_with_closure_explicit<F>(rules: F) -> uint where F: for<'a> FnOnce(&'a mut uint) -> () {
    let mut i = 0;
    rules(&mut i);

    i
}

pub fn main() {
    initialize_with_closure(|i: &mut uint| *i = *i + 20);
    initialize_with_closure_explicit(|i: &mut uint| *i = *i + 20);
}

ベビーサークル

于 2015-01-07T08:48:01.383 に答える