不能将'Fn`闭包中捕获的外部变量借用为可变

时间:2015-05-31 15:20:27

标签: rest rust nickel

这是我与Rust的第一天,但​​我正在努力做一些微不足道的事情,而且我被困住了。

我要做的是向Vector添加一个结构,然后返回结果。我正在尝试创建一个非常简单的REST服务,它将在发布时将数据存储在内存中,并在执行GET时以JSON格式返回所有数据。

这是我目前的代码:

fn main() {
    let mut server = Nickel::new();
    let mut reservations = Vec::new();

   server.post("/reservations/", middleware! { |request, response|
        let reservation = request.json_as::<Reservation>().unwrap();

        reservations.push(reservation); // <-- error occurs here

        format!("Hello {} {}", reservation.name, reservation.email)

    });

    server.listen("127.0.0.1:3000");
}

我尝试使用RefCell this solution,但后来我得到了Vec<reservation::Reservation>未实现特征同步的错误

1 个答案:

答案 0 :(得分:18)

这是Rust如何保护您免受线程不安全的一个很好的例子。

如果您考虑一下,在您当前的代码中,多个线程可能会尝试同时改变reservations而不进行任何同步。这是一场数据竞赛,Rust会抱怨它。

一种可能的解决方案是将reservations向量包装到Mutex以获得同步。您还需要一个Arc(原子引用计数),因为Rust无法证明reservations的寿命比线程长。

通过这些更改,您的代码应如下所示:

use std::sync::{Arc, Mutex};
fn main() {
    let mut server = Nickel::new();
    let reservations = Arc::new(Mutex::new(Vec::new()));

    server.post("/reservations/", middleware! { |request, response|
        let reservation = request.json_as::<Reservation>().unwrap();

        reservations.lock().unwrap().push(reservation); // <-- error occurs here

        format!("Hello {} {}", reservation.name, reservation.email)

    });

    server.listen("127.0.0.1:3000");
}

您可以查看文档,了解有关MutexArc

的其他信息