不能将 `Fn` 闭包中捕获的外部变量借用为可变的
这是我使用 Rust 的第一天,但我正在尝试做一些微不足道的事情,但我被卡住了.
This is my first day with Rust, but I'm trying to do something trivial, and I'm stuck.
我要做的是将一个结构体添加到一个 Vector 中,然后返回结果.我正在尝试创建一个非常简单的 REST 服务,该服务将在发布时将数据存储在内存中,并在执行 GET 时以 JSON 格式返回所有数据.
What I'm trying to do is to add an struct to a Vector, and return the result. What I'm trying is to create a very simple REST service which will store the data in memory when posting, and return all the data in JSON format when doing a GET.
这是我当前的代码:
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 的解决方案,但随后我收到错误消息,即 Vec<:reservation>
I tried this solution with a RefCell, but then I get the error that the trait Sync is not implemented for Vec<reservation::Reservation>
这是 Rust 如何保护您免受线程不安全的一个很好的例子.
This is a very good example of how Rust protects you from thread unsafety.
如果您考虑一下,在您当前的代码中,多个线程可能会尝试在没有任何同步的情况下同时改变 reservations
.这是一场数据竞赛,Rust 会抱怨.
If you think about it, in your current code it would be possible that multiple threads try to concurrently mutate reservations
without any kind of synchronization. This is a data race and Rust will complain about it.
一种可能的解决方案是将 reservations
向量包装到 Mutex
中以获得同步.您还需要一个 Arc
(原子引用计数),因为 Rust 无法证明 reservations
的寿命比线程长.
A possible solution would be to wrap the reservations
vector into a Mutex
to get synchronization. You will also need an Arc
(atomic reference counting), since Rust cannot prove that reservations
will live longer than the threads.
通过这些更改,您的代码应如下所示:
With these changes, your code should be like the following:
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");
}
You can check the documentation for additional info about Mutex
and Arc
.