3

我想要一个在所有处理程序中都可用的上下文结构,但我无法通过编译器。

例如,我想要这样的东西

extern crate iron;
extern crate router;

use iron::prelude::*;
use router::Router;
use std::collections::HashMap;

struct Context {
    cache: HashMap<String, String>,
}

fn main() {
    let mut context = Context { cache: HashMap::new(), };
    let mut router = Router::new();

    router.get("/", |request| index(request, context));

    Iron::new(router).http("localhost:80").unwrap();
}


fn index(_: &mut Request, context: Context) -> IronResult<Response> {
    Ok(Response::with((iron::status::Ok, "index")))
}

这不会编译一个冗长的错误消息

error: type mismatch resolving `for<'r, 'r, 'r> <[closure@src\main.rs:... context:_] as std::ops::FnOnce<(&'r mut iron::Request<'r, 'r>,)>>::Output == std::result::Result<iron::Response, iron::IronError>`:
 expected bound lifetime parameter ,
    found concrete lifetime [E0271]
src\main.rs:...     router.get("/", |request| index(request, context));
4

1 回答 1

4

错误消息在这里几乎无法理解(它有一个问题!)。

问题是没有推断出闭包的类型。我们可以帮助编译器注释类型request

extern crate iron;
extern crate router;

use iron::prelude::*;
use router::Router;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};

#[derive(Clone, Default)]
struct Context {
    cache: Arc<Mutex<HashMap<String, String>>>,
}

fn main() {
    let context = Context::default();
    let mut router = Router::new();

    let c = context.clone();
    router.get("/", move |request: &mut Request| index(request, &c), "index");

    Iron::new(router).http("localhost:8080").unwrap(); // port 80 is privileged
}

fn index(_: &mut Request, context: &Context) -> IronResult<Response> {
    Ok(Response::with((iron::status::Ok, "index")))
}

请注意,我将类型更改context&Context(否则,闭包只会实现 FnOnce)和使用move(闭包必须有'static生命周期才能实现Handler)。

为了使更改成为可能cacheindex您必须将类型更改Arc<Mutex<HashMap<String, String>>>为或类似。

于 2016-08-12T11:30:36.383 回答