I want to start a Hyper server in a function with port
and dao
parameters provided by main()
, but the function only works after I explicitly indicate the 'static
lifetime. This confused me a lot.
extern crate futures;
extern crate hyper;
use futures::future::Future;
use hyper::header::ContentLength;
use hyper::server::{Http, Request, Response, Service};
use std::net::SocketAddr;
trait Dao {}
struct MysqlDao;
impl Dao for MysqlDao {}
struct HelloWorld<'a> {
dao: &'a Dao,
}
const PHRASE: &'static str = "Hello, World!";
impl<'a> Service for HelloWorld<'a> {
type Request = Request;
type Response = Response;
type Error = hyper::Error;
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
fn call(&self, _req: Request) -> Self::Future {
Box::new(futures::future::ok(
Response::new()
.with_header(ContentLength(PHRASE.len() as u64))
.with_body(PHRASE),
))
}
}
fn main() {
let addr = "127.0.0.1:3000".parse().unwrap();
let dao = MysqlDao;
let server = Http::new()
.bind(&addr, move || Ok(HelloWorld { dao: &dao }))
.unwrap();
server.run().unwrap();
}
The Http::new().bind
API documententation said it needs a NewService + 'static
, so I think the compiler would infer the dao
variant is 'static
, but when I move the last three statements out of main, it can't infer!
fn main() {
let addr = "127.0.0.1:3000".parse().unwrap();
let dao: MysqlDao = MysqlDao;
web_startup(&addr, &dao);
}
fn web_startup<T: Dao>(addr: &SocketAddr, dao: &T) {
let server = Http::new()
.bind(addr, move || Ok(HelloWorld { dao }))
.unwrap();
server.run().unwrap();
}
I get the error:
error[E0477]: the type `[closure@src/main.rs:44:21: 44:51 dao:&T]` does not fulfill the required lifetime
--> src/main.rs:44:10
|
44 | .bind(addr, move || Ok(HelloWorld { dao }))
| ^^^^
|
= note: type must satisfy the static lifetime
So I fixed it:
fn main() {
let addr = "127.0.0.1:3000".parse().unwrap();
static DAO: MysqlDao = MysqlDao;
web_startup(&addr, &DAO);
}
fn web_startup<T: Dao>(addr: &SocketAddr, dao: &'static T) {
let server = Http::new()
.bind(addr, move || Ok(HelloWorld { dao }))
.unwrap();
server.run().unwrap();
}
I don't understand why I should use the static
keyword for static DAO: MysqlDao = MysqlDao;
statement but need not before change the code. The compiler couldn't infer it or am I thinking about things incorrectly?