【问题标题】:`for<'r, 'r, 'r> ...` cannot be sent between threads safely`for<'r, 'r, 'r> ...` 无法在线程之间安全发送
【发布时间】:2017-01-01 16:20:39
【问题描述】:

我学习了 Rust,并尝试构建一个基于 hyper 的微路由系统(这只是为了学习目的,我知道框架存在)。

我不知道如何与hyper::server::Handler 共享“复杂”类型。我阅读了错误消息,但不幸的是,我不明白如何修复它(大多数时候,rust 编译器只是说要修复什么,现在我不确定)。

这是我尝试过的(非)工作过度简化的示例:

extern crate hyper;
use std::sync::Mutex;

use hyper::*;

type Route = (method::Method, String, Box<Fn(server::Request, server::Response)>);

struct MyHandler {
    routes: Mutex<Vec<Route>>
}

impl server::Handler for MyHandler {
    fn handle(&self, req: server::Request, mut res: server::Response) {
        // This is not important
    }
}

fn main() {
    // This is not important
}

错误是:

error: the trait bound `for<'r, 'r, 'r> std::ops::Fn(hyper::server::Request<'r, 'r>, hyper::server::Response<'r>) + 'static: std::marker::Send` is not satisfied [--explain E0277]
  --> src/main.rs:12:10
   |>
12 |>     impl server::Handler for MyHandler {
   |>          ^^^^^^^^^^^^^^^
note: `for<'r, 'r, 'r> std::ops::Fn(hyper::server::Request<'r, 'r>, hyper::server::Response<'r>) + 'static` cannot be sent between threads safely
note: required because it appears within the type `Box<for<'r, 'r, 'r> std::ops::Fn(hyper::server::Request<'r, 'r>, hyper::server::Response<'r>) + 'static>`
note: required because it appears within the type `(hyper::method::Method, std::string::String, Box<for<'r, 'r, 'r> std::ops::Fn(hyper::server::Request<'r, 'r>, hyper::server::Response<'r>) + 'static>)`
note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<(hyper::method::Method, std::string::String, Box<for<'r, 'r, 'r> std::ops::Fn(hyper::server::Request<'r, 'r>, hyper::server::Response<'r>) + 'static>)>`
note: required because it appears within the type `alloc::raw_vec::RawVec<(hyper::method::Method, std::string::String, Box<for<'r, 'r, 'r> std::ops::Fn(hyper::server::Request<'r, 'r>, hyper::server::Response<'r>) + 'static>)>`
note: required because it appears within the type `std::vec::Vec<(hyper::method::Method, std::string::String, Box<for<'r, 'r, 'r> std::ops::Fn(hyper::server::Request<'r, 'r>, hyper::server::Response<'r>) + 'static>)>`
note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Mutex<std::vec::Vec<(hyper::method::Method, std::string::String, Box<for<'r, 'r, 'r> std::ops::Fn(hyper::server::Request<'r, 'r>, hyper::server::Response<'r>) + 'static>)>>`
note: required because it appears within the type `MyHandler`
note: required by `hyper::server::Handler`

如果我使用简单的整数,它可以工作,但不能使用 Route 类型。

因此,该特征存在问题,并且“无法在线程之间安全地发送”。阅读hyper 文档,我添加了Mutex,但我一定很笨,我不知道我在做什么,不确定我是应该停止学习 Rust,还是继续尝试。

【问题讨论】:

    标签: rust hyper


    【解决方案1】:

    你快到了。

    错误是说MyHandler 没有实现Send trait,这意味着一个类型可以安全地发送到其他线程:

    note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Mutex<std::vec::Vec<(hyper::method::Method, std::string::String, Box<for<'r, 'r, 'r> std::ops::Fn(hyper::server::Request<'r, 'r>, hyper::server::Response<'r>) + 'static>)>>`
    note: required because it appears within the type `MyHandler`
    note: required by `hyper::server::Handler`
    

    该错误确实指向了正确的位置,但它有点压倒性。第一行是:

    note: `for<'r, 'r, 'r> std::ops::Fn(hyper::server::Request<'r, 'r>, hyper::server::Response<'r>) + 'static` cannot be sent between threads safely
    

    也就是说Fn 类型没有实现Send。这是您的Route 类型中的一个:

    type Route = (method::Method, String, Box<Fn(server::Request, server::Response)>);
    

    一个Fn闭包只有Send如果它捕获的所有变量也是Send,但是这里我们不知道传入的任何闭包是否合适。

    解决方案很简单:将Fn 类型约束为Send

    type Route = (method::Method, String, Box<Fn(server::Request, server::Response)+Send>);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-16
      • 2021-11-30
      • 1970-01-01
      • 2021-12-07
      • 2014-06-14
      • 1970-01-01
      相关资源
      最近更新 更多