6

私はRustを学び、ハイパーの上に構築されたマイクロルートシステムを構築しようとしました(これは学習目的のためであり、フレームワークが存在することは知っています)。

「複雑な」型を と共有する方法がわかりません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 の学習をやめるべきなのか、それとも挑戦し続けるべきなのかわかりません。

4

1 に答える 1

8

もうすぐそこです。

エラーは、それがトレイトを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>);
于 2016-08-25T11:00:00.600 に答える