【问题标题】:Cannot borrow captured outer variable in an `Fn` closure as mutable不能在“Fn”闭包中将捕获的外部变量借用为可变的
【发布时间】:2015-08-14 01:28:00
【问题描述】:

这是我使用 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&lt;reservation::Reservation&gt; 实现特征同步

【问题讨论】:

    标签: rest rust nickel


    【解决方案1】:

    这是 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");
    }
    

    您可以查看文档以获取有关 Mutex 和 Arc 的更多信息。

    【讨论】:

    • 最喜欢的帖子,非常感谢 Erik Pragt 的提问和 @aochagavia 的回答。
    猜你喜欢
    • 2016-12-24
    • 2016-02-13
    • 2019-10-14
    • 1970-01-01
    • 2015-10-16
    • 2020-01-16
    • 2020-01-01
    • 2016-05-02
    相关资源
    最近更新 更多