不能将 `Fn` 闭包中捕获的外部变量借用为可变的 [英] Cannot borrow captured outer variable in an `Fn` closure as mutable

查看:52
本文介绍了不能将 `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

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

您可以查看文档以获取有关 Mutex<代码>弧形.

You can check the documentation for additional info about Mutex and Arc.

这篇关于不能将 `Fn` 闭包中捕获的外部变量借用为可变的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆