问题
I'm currently pulling my hear out over this one. I tried to shrink it down to a minimal reproducible example.
struct Request;
struct ResponseWriter<'a> {
dummy: &'a ()
}
#[deriving(Clone)]
pub struct RouteStore{
pub routes: Vec<Route>,
}
#[deriving(Clone)]
struct Route {
path: String,
handler: fn(request: &Request, response: &mut ResponseWriter)
}
impl RouteStore {
pub fn new () -> RouteStore {
RouteStore {
routes: Vec::new()
}
}
fn add_route (&mut self, path: String, handler: fn(request: &Request, response: &mut ResponseWriter)) -> () {
let route = Route {
path: path,
handler: handler
};
self.routes.push(route);
}
}
fn main () {
}
This leaves me with:
error: mismatched types: expected `fn(&http::server::request::Request, &mut http::server::response::ResponseWriter<>)` but found `fn(&http::server::request::Request, &mut http::server::response::ResponseWriter<>)` (expected concrete lifetime, but found bound lifetime parameter )
src/so.rs:12 handler: fn(request: &Request, response: &mut ResponseWriter)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Previously I stored my fn
in a HashMap
like this HashMap<String, fn(request: &Request, response: &mut ResponseWriter)>
. This worked fine.
But now I want to refactor things a bit and introduced a Route
struct and store things as Vec<Route>
. But suddenly hell breaks loose and I don't know how to fix it :-/
For the curious ones, this is part of my effort to write an expressjs inspired web framework for Rust called Floor
回答1:
After making your example a bit more minimal (getting rid of the http
dependency), and some suggestions on IRC (namely someone pointing out that the problem goes away if you remove the deriving(Clone)
from the Route
), you can see a fixed version below (--cfg v2
)
#[deriving(Clone)]
pub struct RouteStore{
pub routes: Vec<Route>,
}
#[cfg(v1)]
#[deriving(Clone)]
struct Route {
path: String,
handler: fn(response: &mut ())
}
#[cfg(v2)]
struct Route {
path: String,
handler: fn(response: &mut ())
}
#[cfg(v2)]
impl Clone for Route {
fn clone(&self) -> Route {
Route { path: self.path.clone(), handler: self.handler }
}
}
impl RouteStore {
pub fn new () -> RouteStore {
RouteStore {
routes: Vec::new()
}
}
fn add_route (&mut self, path: String, handler: fn(response: &mut ())) -> () {
let route = Route {
path: path,
handler: handler
};
self.routes.push(route);
}
}
fn main () {
}
The issue here is that an (edit: Well, it does have a fn
does not implement Clone
.clone
method, but the returned value does not seem compatible with what that field needs. The v2
version above just side-steps the whole issue.)
So I suspect the error you are seeing is coming from the auto-generated clone implementation that deriving(Clone)
injects.
来源:https://stackoverflow.com/questions/24162518/how-to-fix-expected-concrete-lifetime-but-found-bound-lifetime-parameter