有人能帮我用新的未装箱闭包重写这段代码吗

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,), ()> {
                                                                                   ^~~~~~~~~~~~

我需要具体说明什么生命周期 ?Simplified example in the sandbox

推荐答案

这需要higher rank trait bounds个更高级别的生命周期.完整的未加修饰的语法是F: for<'a> FnOnce<(&'a mut Builder,), ()>.

在函数上使用一辈子是行不通的,例如,如果我们

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

这意味着build适用于调用方希望的任何生存期(例如,他们可以 Select 'b=='static),但这是无效的,因为需要使用一个特定的具体生存期:函数中&mut builder的生存期.在一个边界中使用F: for<'a> ...表示F与任何生存期'a一起工作,因此编译器认为在&mut builder中替换一个是合法的.

正如我在上面所暗示的,这是真正丑陋的无装饰语法.有两种连续的方法可以让它变得更好.首先,使用闭合特性的标准方法是()糖:for<'a> FnOnce(&'a mut Builder) -> (),或者像其他Rust 一样,-> ()糖可以go 掉:for<'a> FnOnce(&'a mut Builder).(注意,这只是FnOnce<...>的糖分,但只有糖分语法在1.0时与这些特征交互时才会稳定.)

然后,paren语法有一个额外的规则:它会自动插入像for<'a>一样的生命周期(具体来说,它会经历lifetime elision,任何插入的生命周期都会被放入trait 的for中),所以只有F: FnOnce(&mut Builder)相当于F: for<'a> FnOnce(&'a mut Builder),这是推荐的版本.

将这些修复应用于playpen示例:

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);
}

playpen

Rust相关问答推荐

如何在Rust中为具有多个数据持有者的enum变体编写文档 comments ?

泛型属性比较

无法理解铁 rust &S错误处理

如何格式化传入Rust中mysql crate的Pool::new的字符串

在复制类型中使用std::ptr::WRITE_VILAR进行内部可变性的安全性(即没有UnSafeCell)

使用关联类型重写时特征的实现冲突

为什么&;mut buf[0..buf.len()]会触发一个可变/不可变的borrow 错误?

获取已知数量的输入

如何将生存期参数添加到框<>;具有dyn类型别名

UnsafeCell:它如何通知 rustc Select 退出基于别名的优化?

在 Rust 中,在第一个空格上分割字符串一次

如何使用 Bincode 在 Rust 中序列化 Enum,同时保留 Enum 判别式而不是索引?

在多核嵌入式 Rust 中,我可以使用静态 mut 进行单向数据共享吗?

rust tokio::spawn 在 mutexguard 之后等待

返回迭代器的特征

Rust/Serde/HTTP:序列化`Option`

判断 is_ok 后重用结果

当我在 struct 中存储异步函数时,为什么它需要生命周期

当特征函数依赖于为 Self 实现的通用标记特征时实现通用包装器

为什么这个闭包没有比 var 长寿?