2016-08-25 3 views
3

녹을 배우고 하이퍼 위에 구축 된 마이크로 경로 시스템을 만들려고했습니다. (학습 목적으로 만 존재하며, 프레임 워크가 있다는 것을 알고 있습니다.)`for <'r, 'r, 'r> ...`스레드간에 안전하게 전송할 수 없습니다.

"복잡한"유형을 hyper::server::Handler과 공유하는 방법을 모르겠습니다. 나는 오류 메시지를 읽었지만, 불행히도, 나는 그것을 고치는 방법을 이해하지 못한다. (대부분 녹슬지 않는 컴파일러가 무엇을 고쳐야하는지, 지금은 이해할 수 없다). 여기

내가 뭘하려의 (비) 작업을 통해 단순화 된 예입니다

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을 추가했으나 바보가되어야합니다. 은 내가 무엇을하고 있는지 전혀 알지 못합니다. 녹을 배우기를 멈추거나 노력을 계속해야하는지 확실하지 않습니다.

답변

5

거의 다 왔어.

오류가 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` 

오류가 바로 이곳에 지점을하지 않습니다, 그러나 그것은이다 조금 압도적이다. 첫 번째 줄은 : Fn 유형 Send를 구현하지 않는 것을 말하는 어떤

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

. 이것은 당신의 Route 유형의 하나입니다 : 그것은 캡처 모든 변수도 Send 경우

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

Fn 폐쇄는 Send이지만, 우리는 여기에서 전달 된 폐쇄 적합 여부를 알 수 없습니다.

해결책은 간단하다 : Send가되도록 Fn 유형을 제한 : 슈퍼 명확한

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

합니다. 감사! –