如何将代码重写为新的未装箱的闭包

Sta*_*rov 9 rust rust-obsolete

有人可以帮我用新的无盒装闭包重写这段代码:

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

    builder
}
Run Code Online (Sandbox Code Playgroud)

我试着像这样写,但我得到了一生的错误:

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,), ()> {
                                                                                   ^~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

我需要指定什么生命周期?沙盒中的简化示例.

huo*_*uon 12

这需要更高级别的特征界限,特别是更高级别的生命周期.完全没有语法的语法是F: for<'a> FnOnce<(&'a mut Builder,), ()>.

在函数上使用生命周期是行不通的,例如,如果我们有

pub fn build<'b, F>(rules: F) -> Builder where F: FnOnce<(&'b mut Builder,), ()>
Run Code Online (Sandbox Code Playgroud)

这表示它build适用于调用者希望的任何生命周期(例如,他们可以选择'b== 'static),但这是无效的,因为需要使用特定的具体生命周期:&mut builder函数内部的生命周期.F: for<'a> ...在一个绑定中使用说,它F适用于任何生命周期'a,因此编译器认为在其中一个替换是合法的&mut builder.

正如我在上面暗示的那样,这是非常丑陋的无语言语法.有两种连续的方法可以做得更好.首先,使用封闭特征的规范方法是()糖:for<'a> FnOnce(&'a mut Builder) -> ()或者,与Rust的其余部分一样,-> ()可以丢弃:for<'a> FnOnce(&'a mut Builder).(注意,这只是糖FnOnce<...>,但只有加糖的语法才能稳定下来,以便在1.0处与这些特征相互作用.)

然后,paren语法有一个额外的规则:它会自动插入一些行为的生命周期for<'a>(具体来说,它会在生命中经历任何插入生命周期的生命周期省略for),所以恰好F: 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);
}
Run Code Online (Sandbox Code Playgroud)

围栏