如何在处理程序之间传递变量

时间:2016-08-12 10:24:00

标签: rust iron

我希望有一个在所有处理程序中都可用的context-struct,但我无法通过编译器。

举个例子,我想要这样的东西

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));

1 个答案:

答案 0 :(得分:4)

这里的错误消息几乎是不可理解的(它有一个issue!)。

问题是没有推断出闭包的类型。我们可以帮助编译器注释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(否则,关闭只会implements FnOnce)并使用move(关闭必须有'static个生命周期来实施Handler)。

为了能够更改cache中的index,您必须change类型为Arc<Mutex<HashMap<String, String>>>或类似。