`for<'r, 'r, 'r> ...` 不能在线程间安全发送
`for<'r, 'r, 'r> ...` cannot be sent between threads safely
我学习了 Rust,我尝试构建一个基于 hyper 的微路由系统(这只是为了学习目的,我知道框架存在)。
我不知道如何与 hyper::server::Handler
共享 "complex" 类型。我阅读了错误消息,但不幸的是,我不知道如何修复它(大多数时候,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
类型。
因此,特征和 "cannot be sent between threads safely" 有问题。阅读 hyper
文档,我添加了一个 Mutex
,但我一定很笨,我不知道我在做什么,不确定我是否应该停下来学习 Rust,或者继续尝试。
你快到了。
错误是说 MyHandler
没有实现 Send
特性,这意味着一个类型可以安全地发送到其他线程:
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>);
我学习了 Rust,我尝试构建一个基于 hyper 的微路由系统(这只是为了学习目的,我知道框架存在)。
我不知道如何与 hyper::server::Handler
共享 "complex" 类型。我阅读了错误消息,但不幸的是,我不知道如何修复它(大多数时候,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
类型。
因此,特征和 "cannot be sent between threads safely" 有问题。阅读 hyper
文档,我添加了一个 Mutex
,但我一定很笨,我不知道我在做什么,不确定我是否应该停下来学习 Rust,或者继续尝试。
你快到了。
错误是说 MyHandler
没有实现 Send
特性,这意味着一个类型可以安全地发送到其他线程:
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>);