私はHyper 0.10で単純なメモリ内URL短縮語を実装することでRustを学習しようとしています。私は私が私のハンドラ内で変更可能なHashMap
を超える閉鎖しようとすることで引き起こされていると思う問題に実行しているよ:ハイパーハンドラー間でHashMapを共有するにはどうすればいいですか?
fn post(mut req: Request, mut res: Response, short_uris: &mut HashMap<&str, &str>) {
let mut body = String::new();
match req.read_to_string(&mut body) {
Ok(_) => {
let key = short_uris.len();
short_uris.insert(&key.to_string(), &body.to_string());
*res.status_mut() = StatusCode::Created;
res.start().unwrap().write(&key.to_string().into_bytes());
},
Err(_) => *res.status_mut() = StatusCode::BadRequest
}
}
fn get(req: Request, mut res: Response, short_uris: &HashMap<&str, &str>) {
match req.uri.clone() {
AbsolutePath(path) => {
match short_uris.get::<str>(&path) {
Some(short_uri) => {
*res.status_mut() = StatusCode::MovedPermanently;
res.headers_mut().set(Location(short_uri.to_string()));
},
None => *res.status_mut() = StatusCode::NotFound
}
},
_ => *res.status_mut() = StatusCode::BadRequest
}
}
fn main() {
let mut short_uris: HashMap<&str, &str> = HashMap::new();
short_uris.insert("/example", "http://www.example.com");
Server::http("0.0.0.0:3001").unwrap().handle(move |req: Request, mut res: Response| {
match req.method {
hyper::Post => post(req, res, &mut short_uris),
hyper::Get => get(req, res, &short_uris),
_ => *res.status_mut() = StatusCode::MethodNotAllowed
}
}).unwrap();
}
src/main.rs:42:40: 42:46 error: the trait bound `for<'r, 'r, 'r> [[email protected]/main.rs:42:47: 48:3 short_uris:std::collections::HashMap<&str, &str>]: std::ops::Fn<(hyper::server::Request<'r, 'r>, hyper::server::Response<'r>)>` is not satisfied [E0277]
src/main.rs:42 Server::http("0.0.0.0:3001").unwrap().handle(move |req: Request, mut res: Response| {
Arc
は、スレッド間HashMap
を共有するために私が使用する必要がありますか?もしそうなら、どのように見えますか?また、私はこの問題について完全に間違っている可能性があります。エラーメッセージは私には非常にわかりにくいです。
なぜグローバルとしてHashMapを宣言していないのですか? –
@ Dr.Sahib私は一般的にグローバルな状態を避けようとしています。また、グローバル状態の使用を最小限に抑えることを推奨した次のSOの記事を読んでいます:http://stackoverflow.com/questions/27791532/how-do-i-create-a-global-mutable-singletonだから私はグローバルな状態なしでそれをやろうとしていました。 – forTruce
夜間のRustに注意するだけで、ここではより良いエラーメッセージが表示されます:「Fn'特性を実装するクロージャが期待されますが、このクロージャは 'FnMut'しか実装しません」 – krdln