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

Eri*_*agt 14 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");
}
Run Code Online (Sandbox Code Playgroud)

我用RefCell 尝试了这个解决方案,但后来我得到了没有实现特征同步的错误Vec<reservation::Reservation>

aoc*_*via 20

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

如果你考虑一下,在你当前的代码中,多个线程可能会在reservations没有任何同步的情况下同时发生变异.这是一场数据竞赛,Rust会抱怨它.

一种可能的解决方案是将reservations向量包装到a中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");
}
Run Code Online (Sandbox Code Playgroud)

您可以查看文档以获取有关Mutex和的其他信息Arc.

  • “这是一个很好的例子,说明 Rust 如何迫使你为只能在单个线程上运行的东西编写低效、冗长和复杂的代码”(在很多情况下) (4认同)
  • 有史以来最喜欢的帖子,非常感谢 Erik Pragt 提出的问题和 @aochagavia 的答案。 (3认同)
  • @Dominic 准确地说:我是一个 Rust 新手,正在编写一个单线程应用程序,并且正在为这个问题而苦苦挣扎。 (2认同)